Элемент фильтра не отображается как в браузере

Я пытаюсь создать свой собственный атлас неба, используя изображения созвездий Викимедиа в SVG. Если вы отображаете их в браузере, фон - за исключением области самого созвездия - выглядит сплошным средне-серым. Чтобы проверить, как это может быть отображено в приложении Java, я взял класс SVGApplication из документации Batik. Это работает - почти: серый фон теперь уменьшен до нескольких прямоугольников с широкими белыми промежутками между ними.

Результат применения SVGA

Насколько я могу расшифровать SVG, это определение и использование фильтра:

<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     width="485.028pt" height="456.053pt"
     viewBox="0 0 485.028 456.053" version="1.1">
<!-- ... -->
<filter id="alpha" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
  <feColorMatrix type="matrix" in="SourceGraphic" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="mask0">
  <g filter="url(#alpha)">
    <rect x="0" y="0" width="486" height="457" style="fill:rgb(100%,100%,100%);fill-opacity:0.149994;stroke:none;"/>
  </g>
</mask>
<clipPath id="clip4">
  <rect width="421" height="385"/>
</clipPath>
<!-- ... -->
</svg>

Java-код очень прост, используя JFileChooser, чтобы выбрать файл и передать ему JSVGCanvas. Основные линии:

    JFrame f = new JFrame("Batik");
    final JPanel panel = new JPanel(new BorderLayout());
    JSVGCanvas svgCanvas = new JSVGCanvas();
    panel.add("Center", svgCanvas);
    File file = new File( "aaa.svg" );
    svgCanvas.setURI(file.toURI().toURL().toString());
    f.getContentPane().add( panel );
    f.setSize(600, 600);
    f.setVisible(true);

Что нужно сделать, чтобы фон выглядел как в браузере?

Редактировать Это упрощенная версия SVG, имеющая тот же эффект - работает в браузере, но не в программе Java.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
      width="485.028pt" height="456.053pt"
      viewBox="0 0 485.028 456.053" version="1.1">
    <defs>
    <filter id="alpha" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
      <feColorMatrix type="matrix" in="SourceGraphic" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
    </filter>
    <mask id="mask0">
      <g filter="url(#alpha)">
    <rect x="0" y="0" width="486" height="457" style="fill:rgb(100%,100%,100%);fill-opacity:0.149994;stroke:none;"/>
      </g>
    </mask>

    <g id="surface2">
    <path style=" stroke:none;fill-rule:nonzero;fill:rgb(13.730068%,12.159915%,12.54902%);fill-opacity:1;" d="M 376.316406 213.578125 L 351.210938 219.398438 L 333.015625 222.675781 L 336.652344 243.417969 L 309.726562 248.511719 L 310.457031 254.695312 L 296.265625 256.878906 L 282.4375 258.335938 L 285.347656 287.808594 L 278.070312 289.265625 L 282.4375 339.847656 L 272.976562 340.9375 L 274.070312 350.035156 L 244.597656 351.855469 L 207.480469 353.308594 L 183.828125 352.21875 L 184.554688 329.292969 L 201.660156 248.511719 L 176.914062 247.417969 L 154.355469 245.964844 L 125.246094 242.6875 L 127.429688 226.3125 L 109.964844 223.402344 L 86.675781 219.035156 L 65.570312 214.304688 L 69.210938 199.75 L 48.46875 195.015625 L 16.449219 184.464844 L 52.835938 71.296875 L 71.390625 76.753906 L 91.40625 82.210938 L 84.855469 111.324219 L 117.242188 117.511719 L 122.335938 92.402344 L 169.273438 98.222656 L 167.089844 114.960938 L 188.558594 116.054688 L 238.046875 133.886719 L 253.328125 114.960938 L 277.707031 112.050781 L 303.90625 108.050781 L 317.003906 66.203125 L 336.652344 61.105469 L 353.027344 55.648438 L 399.605469 206.664062 L 376.316406 213.578125 Z M 0.800781 384.96875 L 420.34375 384.96875 L 420.34375 0.335938 L 0.800781 0.335938 L 0.800781 384.96875 Z M 0.800781 384.96875 "/>
    </g>

    </defs>
    <g id="surface0">
    <use xlink:href="#surface2"  transform="matrix(1,0,0,1,33,18)" mask="url(#mask0)"/>
    </g>
</svg>

(Я признаю, что у меня нет опыта работы с SVG. Я готов к RTFM, но с чего мне начать?)

1 ответ

Решение

Если вы предполагаете, что комбинация маски и фильтра вызывает проблемы с батиком, попробуйте этот обходной путь.

Мы сделаем бы быструю и грязную замену нарушающего элемента чем-то, что является близким эквивалентом.

Примерно через девять строк в конце файла вы найдете следующее:

<use xlink:href="#surface2" transform="matrix(1,0,0,1,33,18)" mask="url(#mask0)"/>

Попробуйте изменить это на

<use xlink:href="#surface2" transform="matrix(1,0,0,1,33,18)" opacity="0.15"/>

Модифицированный файл выглядит так же, как оригинал, и отлично работает в батике - по крайней мере, для меня.

Надеемся, что остальные ваши файлы SVG имеют одинаковое расположение файлов и их так же легко исправить.

Удачи!

Другие вопросы по тегам