4

我想在 javafx 2.0 中显示一个 svg 图像,但我在 API 中找不到这样的东西。我想这是因为它仍处于测试阶段。

在最终版本之前,我如何加载 svg ?是否已经有一个可以处理的库,还是我需要自己解析文件然后创建相应的形状?

谢谢

4

5 回答 5

8

根据这个问题的答案,我找到了一个可行的解决方案。

1. 包括对Batik SVG Toolkit jars的引用

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);

希望这会有所帮助!

于 2011-07-28T21:36:46.007 回答
3

我在上面使用了@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);

更简单,而且对我来说效果更好。

于 2012-12-17T15:45:28.783 回答
1

试试http://forums.oracle.com/forums/thread.jspa?threadID=2264379&tstart=0

于 2011-08-05T20:54:52.747 回答
1

你不需要蜡染,你可以像这样尝试 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");
于 2012-01-09T05:15:17.927 回答
0

将 SVG 转换为 FXML,然后它就变得微不足道了。可以使用 XSLT 完成转换。您可以从这里获取样式表:

http://jayskills.com/blog/2012/06/03/svg-to-fxml-using-netbeans/

然后在转换为 FXML 后,您可以使用内置的 FXMLLoader 将其作为节点加载:

FXMLLoader.setDefaultClassLoader(this.getClass().getClassLoader());
URL location = KayakMain.class.getResource("path/to/my/resource.fxml");
Parent root = FXMLLoader.load(location);
于 2012-08-22T17:32:49.153 回答