web-dev-qa-db-ja.com

JavaFX 2.2のSVG画像

私はJavaFX 2.2を初めて使用しますが、今のところ、JavaFX 2.2アプリケーションでSVG画像を表示する方法を見つけることができませんでした。 Batikを見てみましたが、_javafx.ImageView_ではなくBufferedImagesに変換されるため、私にとってはうまくいきませんでした。

JavaFXアプリケーションでSVG画像を表示する方法はありますか?または、少なくともJavaFXからSVG画像をエクスポートできますか?関数Node.snapshot()は何らかの形でそこに役立ちますか?

25
user1582432

JavaFXアプリケーションでSVG画像を表示する方法はありますか?

以下にいくつかのオプションを示します。

  1. WebView および load を作成して、WebViewのWebEngineにsvgイメージを作成します。
  2. e(fx)clipse プロジェクトには、 svgからfxmlへのコンバーター (リンク切れ:().
  3. これは NetBeansプラグイン もsvgをfxmlに変換します(リンクは現在無効です:()。
  4. Batiksvgsalamander のようなawtベースのライブラリを使用して、結果のBufferedImageをJavaFX Imageに変換できます。
  5. JavaFX 2.2には、最小限の SVGPath 文字列(完全なSVG仕様ではない)のサポートがネイティブに含まれています。
  6. JavaFX Canvas GraphicsContext コマンドを使用してsvgをレンダリングするコンバーターを作成できます。
  7. FranzXaver は、SVGLoaderを提供します。その使用法は、次の回答に示されています。 JavaFXのボタンにSVGファイルをロードする

または、少なくともjavafxからSVG画像をエクスポートできますか?

この機能は、JavaFX SceneGraph to svgコンバーターのように聞こえます。理論的には可能ですが、そのようなツールを誰もが作成していないことを私はまだ知りません。

Node.snapshot()関数は何らかの方法で役立ちますか?

Node.snapshot() は、svgはベクトルベースの形式であり、ノードスナップショットはビットマップ形式であるため、JavaFXシーングラフからsvg画像をエクスポートするのに役立ちません。

Batikを見てみましたが、javafx.ImageViewではなくBufferedImagesに変換されるため、私にとってはうまくいきませんでした。

SwingFXUtils を使用すると、awt BufferedImagesとjavafxイメージを簡単に変換できます。

パフォーマンスに関しては、どの方法をお勧めしますか?

複雑なsvgの場合、fxmlからのレンダリングではなく、ビットマップ画像またはキャンバスグラフィックスコンテキストへのレンダリングのパフォーマンスが向上する可能性があります。これは、シーングラフが非常にシンプルで、ノードがはるかに少ないためです。つまり、javafxランタイムの作業量がはるかに少ないためです。単純なsvg(<1000ノードが生成される)の場合、おそらくそれほど重要ではありません。

Javafx.scene.shape.SVGPathのインスタンスの作成について、SVGをFXMLに変換していますか?

部分的に。完全な SVG仕様 は、基本的な形状よりもはるかに広い範囲をカバーします。さらに、グラデーション、エフェクト、アニメーションなどをSVGで実行できます。したがって、ソースSVGイメージにこれらの追加アイテムが含まれる場合、それらもFXMLに変換する必要があります(可能な限り、FXMLに変換するのが難しいスクリプトなどのSVGのいくつかの側面があります)。

私の推測では、SVG仕様のサイズと複雑さが、JavaFXコアAPIに完全なSVG画像システムの直接のサポートが現在含まれておらず、代わりにSVGPathなどの限られた同様の機能のみが提供されている理由の1つであると思われます。 JavaFXコアAPIでSVGをネイティブに実装することは、他の望ましいアイテムと比較した場合、比較的少ない報酬で高いコストになっていたでしょう。

その場合、#2(および#3)と#5はまったく同じではないでしょうか?

いいえ。#2および#3で参照されているNetBeansおよびEclipseツールは、#5で説明されているSVGPath機能よりも機能的でした。これらのツールは、SVG仕様の追加の側面を同等のFXML(例:グラデーション、効果、変換)に変換したためです。

43
jewelsea

上記のトランスコーダークラスを使用して、SVGサポートをJavaFXに追加するgithubで小さなプロジェクトを作成しました(ただしJavaFX 8): javafxsvg

電話した後

SvgImageLoaderFactory.install();

sVG画像は、JavaコードまたはCSSの他のサポートされている画像タイプと同じように、どこでも使用できます。

24
Jan Gassen

JavaFX + Batik +カスタムトランスコーダー

BatikをJavaFXと組み合わせて使用​​する完全な例はどこにも見当たらないため、以下に完全なソリューションを提供します。

簡潔にするため、例外処理(たとえば、TranscoderException)を削除したことに注意してください。
フルコードにアクセスできます: https://Gist.github.com/ComFreek/b0684ac324c815232556 =

  1. BatikでSVGファイルを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;
        }
    }
    
  2. トランスコーダーを使用してBufferedImageオブジェクトを生成します。

    BufferedImageTranscoder trans = new BufferedImageTranscoder();
    
    // file may be an InputStream.
    // Consult Batik's documentation for more possibilities!
    TranscoderInput transIn = new TranscoderInput(file);
    
    trans.transcode(transIn, null);
    
  3. BufferedImageオブジェクトをImageオブジェクトに変換します(JavaFXから):

    // Use WritableImage if you want to further modify the image (by using a PixelWriter)
    Image img = SwingFXUtils.toFXImage(trans.getBufferedImage(), null);
    
  4. 最後に、以前に受け取ったオブジェクトをImageViewに割り当てます。

    imgView.setImage(img);
    
9
ComFreek