Подтвердить что ты не робот

SVG-изображение в JavaFX 2.2

Я новичок в JavaFX 2.2, и на данный момент я не смог найти способ отображения SVG-изображений в приложении JavaFX 2.2. Я взглянул на Батика, но это не помогло мне, поскольку оно преобразуется в BufferedImages, а не в javafx.ImageView.

Есть ли способ показать изображение SVG в приложении JavaFX? Или вы можете экспортировать SVG-образ из JavaFX? Помогает ли функция Node.snapshot()?

4b9b3361

Ответ 1

Есть ли способ показать изображение SVG в приложении JavaFX?

Вот несколько вариантов:

  • Создайте WebView и load образ svg в WebView WebEngine.
  • Проект e (fx) clipse включает svg для fxml (ссылка сейчас dead:().
  • Этот плагин NetBeans также преобразует svg в fxml (ссылка now dead:().
  • Вы можете использовать библиотеку на основе awt, например Batik или svgsalamander и преобразовать полученный BufferedImage в образ JavaFX.
  • JavaFX 2.2 изначально включает поддержку некоторых минимальных SVGPath строк (не полная спецификация SVG).
  • Вы можете написать конвертер, который отображает svg, используя команды JavaFX Canvas GraphicsContext.
  • FranzXaver предоставляет SVGLoader, использование которого показано в ответе на: Загрузка SVG файл в Button на JavaFX

Или вы можете экспортировать SVG-образ из javafx?

Эта функция звучит как конвертер JavaFX SceneGraph в svg. Хотя это теоретически возможно, я не знаю, что кто-то еще создал такой инструмент.

Помогает ли функция Node.snapshot()?

Node.snapshot() не поможет экспортировать изображение svg из графика сцены JavaFX, поскольку svg - это векторный формат и node моментальный снимок - это бит-формат.

Я взглянул на Батика, но это не помогло мне, поскольку оно преобразуется в BufferedImages, а не в javafx.ImageView.

Вы можете легко преобразовать между awt BufferedImages и изображениями javafx, используя SwingFXUtils.

С точки зрения производительности - каким образом вы бы порекомендовали?

Для сложных svg, а не для рендеринга из fxml, вы, вероятно, получите лучшую рендеринг производительности в растровом графическом или графическом контексте. Это связано с тем, что граф вашей сцены будет намного проще, с гораздо меньшим количеством узлов, а это значит, что время выполнения javafx будет намного меньше. Для простых svgs (сгенерировано 1000 узлов), вероятно, это не будет иметь большого значения.

Преобразует SVG в FXML о создании экземпляров javafx.scene.shape.SVGPath?

Частично. Полная спецификация SVG охватывает гораздо больше оснований, чем основные формы. Кроме того, градиенты, эффекты, анимации и т.д. Могут выполняться SVG. Поэтому, если исходное изображение SVG включает эти дополнительные элементы, тогда их также нужно преобразовать в FXML (насколько это возможно, будут некоторые аспекты SVG, такие как скрипты, которые трудно перевести на FXML).

Я предполагаю, что размер и сложность спецификации SVG являются одной из причин, по которым прямая поддержка полной системы изображений SVG в настоящее время не включена в базовый API JavaFX, и вместо этого ограниченные аналогичные функции, такие как SVGPath, предложенный. Внедрение SVG изначально в API ядра JavaFX было бы дорогостоящим для относительно небольшого вознаграждения по сравнению с другими желаемыми элементами.

Если это так, не будут ли # 2 (и # 3) и # 5 одинаковыми?

Нет. Инструменты NetBeans и Eclipse, на которые ссылаются в # 2 и # 3, были более функциональными, чем объекты SVGPath, упомянутые в № 5, поскольку эти инструменты преобразовали дополнительные аспекты спецификации SVG в эквиваленты FXML (например, градиенты, эффекты и преобразования).

Ответ 2

Я использовал класс transcoder выше для создания небольшого проекта на github, который добавляет поддержку SVG для JavaFX (хотя JavaFX 8): javafxsvg

После вызова

SvgImageLoaderFactory.install();

вы можете использовать SVG-изображения в любом месте вашего Java-кода или CSS, как и любой другой поддерживаемый тип изображения.

Ответ 3

JavaFX + Batik + Пользовательский транскодер

Поскольку я нигде не нашел полного примера использования Batik в сочетании с JavaFX, я предоставляю полное решение ниже.

Обратите внимание, что я удалил обработку исключений (например, для TranscoderException) для краткости.
Вы можете получить полный код здесь: https://gist.github.com/ComFreek/b0684ac324c815232556

  • Чтобы преобразовать SVG файл с Batik в BufferedImage, вы должны реализовать пользовательский транскодер:

    /**
     * Many thanks to bb-generation for sharing this code!
     * @author bb-generation
     * @link http://bbgen.net/blog/2011/06/java-svg-to-bufferedimage/
     * @link In case the link above is still down: https://web.archive.org/web/20131215231214/http://bbgen.net/blog/2011/06/java-svg-to-bufferedimage/
     */
    
    public class BufferedImageTranscoder extends ImageTranscoder {
    
        private BufferedImage img = null;
    
        @Override
        public BufferedImage createImage(int width, int height) {
            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            return bi;
        }
    
        @Override
        public void writeImage(BufferedImage img, TranscoderOutput to) throws TranscoderException {
            this.img = img;
        }
    
        public BufferedImage getBufferedImage() {
            return img;
        }
    }
    
  • Используйте транскодер для создания объекта BufferedImage:

    BufferedImageTranscoder trans = new BufferedImageTranscoder();
    
    // file may be an InputStream.
    // Consult Batik documentation for more possibilities!
    TranscoderInput transIn = new TranscoderInput(file);
    
    trans.transcode(transIn, null);
    
  • Преобразуйте объект BufferedImage в объект Image (из JavaFX):

    // Use WritableImage if you want to further modify the image (by using a PixelWriter)
    Image img = SwingFXUtils.toFXImage(trans.getBufferedImage(), null);
    
  • Наконец, назначьте ранее полученный объект вашему ImageView:

    imgView.setImage(img);