javafx 2.0でsvg画像を表示したいのですが、APIにそのようなものがありません。まだベータ版だからだと思います。
最終リリースまで、どうすれば svg をロードできますか? それを処理できるライブラリは既にありますか、それともファイルを解析してから対応する形状を作成する必要がありますか?
ありがとう
この質問の答えに基づいて、実用的な解決策を見つけました。
1. Batik SVG Toolkit jarへの参照を含める
2. 独自のトランスコーダーを実装する
( Devon_C_Millerによるこの回答に基づく)
class MyTranscoder extends ImageTranscoder {
private BufferedImage image = null;
@Override
public BufferedImage createImage(int w, int h) {
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
return image;
}
@Override
public void writeImage(BufferedImage img, TranscoderOutput out) {
}
public BufferedImage getImage() {
return image;
}
}
3. svg から BufferedImage を取得します( John Doppelmannによるこの回答
のヒントに基づく)
String uri = "path_to_svg/some.svg";
MyTranscoder transcoder = new MyTranscoder();
TranscodingHints hints = new TranscodingHints();
hints.put(ImageTranscoder.KEY_WIDTH, 20f); //your image width
hints.put(ImageTranscoder.KEY_HEIGHT, 20f); //your image height
hints.put(ImageTranscoder.KEY_DOM_IMPLEMENTATION, SVGDOMImplementation.getDOMImplementation());
hints.put(ImageTranscoder.KEY_DOCUMENT_ELEMENT_NAMESPACE_URI, SVGConstants.SVG_NAMESPACE_URI);
hints.put(ImageTranscoder.KEY_DOCUMENT_ELEMENT, SVGConstants.SVG_SVG_TAG);
hints.put(ImageTranscoder.KEY_XML_PARSER_VALIDATING, false);
transcoder.setTranscodingHints(hints);
TranscoderInput input = new TranscoderInput(url.toExternalForm());
transcoder.transcode(input, null);
BufferedImage bufferedImage = transcoder.getImage();
4. BufferedImage から InputStream を作成する
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
JPEGImageEncoder imageEncoder = JPEGCodec.createJPEGEncoder(outputStream);
imageEncoder.encode(bufferedImage);
byte[] bytes = outputStream.toByteArray();
InputStream inputStream = new ByteArrayInputStream(bytes);
5. ImageView に画像を追加します
//javafx.scene.image.Image
Image image = new Image(inputStream);
//javafx.scene.image.ImageView
ImageView imageView = new ImageView();
imageView.setImage(image);
this.getChildren().add(imageView);
これが役立つことを願っています!
上記の@pmouleの回答を使用しましたが、彼の手順3〜5を次のように置き換えた方が幸運でした:
MyTranscoder imageTranscoder = new MyTranscoder();
imageTranscoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, (float) width);
imageTranscoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, (float) height);
TranscoderInput input = new TranscoderInput(new FileReader(file));
imageTranscoder.transcode(input, null);
BufferedImage bimage = imageTranscoder.getImage();
WritableImage wimage = SwingFXUtils.toFXImage(bimage, null);
ImageView imageView = new ImageView(wimage);
<panel-vbox-whatever>.getChildren().clear();
<panel-vbox-whatever>.getChildren().add(imageView);
よりシンプルで、私にとってはうまくいきました。
バティックは必要ありません。次のように WebView を試すことができます。
WebView view = new WebView();
view.setMinSize(500, 400);
view.setPrefSize(500, 400);
final WebEngine eng = view.getEngine();
eng.load("http://127.0.0.1/demo1.svg");
SVG を FXML に変換すると、簡単になります。変換は XSLT で行うことができます。スタイルシートは以下から入手できます。
http://jayskills.com/blog/2012/06/03/svg-to-fxml-using-netbeans/
次に、FXML に変換した後、組み込みの FXMLLoader を使用して Node としてロードできます。
FXMLLoader.setDefaultClassLoader(this.getClass().getClassLoader());
URL location = KayakMain.class.getResource("path/to/my/resource.fxml");
Parent root = FXMLLoader.load(location);