简单地说,我正在寻找一种使用蜡染库从SVG文件制作ImageIcon的方法。我不想首先将SVG光栅化到磁盘,我只想能够从jar文件中提取svg并将其作为UI元素。我觉得这应该是相当容易的,但蜡染javadoc没有告诉我我需要知道的。(Why蜡染?嗯,我们已经在使用它了,所以我们不必再运行另一个图书馆超过法律的。)
eoxn13cs1#
这真的很简单,只是不是很直观。需要扩展ImageTranscoder。在createImage方法中,分配一个BufferedImage,将其缓存为成员变量,并返回它。writeImage方法为空。并且需要添加一个getter来检索BufferedImage。它看起来像这样:
ImageTranscoder
createImage
BufferedImage
writeImage
class MyTranscoder extends ImageTranscoder { private BufferedImage image = null; public BufferedImage createImage(int w, int h) { image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); return image; } public void writeImage(BufferedImage img, TranscoderOutput out) { } public BufferedImage getImage() { return image; } }
现在,要创建一个图像,您需要创建一个代码转换器的示例,并通过设置TranscodingHints将所需的宽度和高度传递给它。最后,您需要从一个TranscoderInput代码转换为一个null目标。然后调用代码转换器上的getter来获取图像。调用看起来像这样:
TranscodingHints
MyTranscoder transcoder = new MyTranscoder(); TranscodingHints hints = new TranscodingHints(); hints.put(ImageTranscoder.KEY_WIDTH, width); hints.put(ImageTranscoder.KEY_HEIGHT, height); transcoder.setTranscodingHints(hints); transcoder.transcode(new TranscoderInput(url), null); BufferedImage image = transcoder.getImage();
很简单,对吗?(是的,对。我只花了2个星期就想明白了。唉。)
kxkpmulp2#
我刚刚用蜡染-1.7遵循了德文郡的方法然而,为了使它工作,我必须对hints对象进行以下添加:
MyTranscoder transcoder =new MyTranscoder() DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); TranscodingHints hints = new TranscodingHints(); hints.put(ImageTranscoder.KEY_WIDTH, width); // e.g. width=new Float(300) hints.put(ImageTranscoder.KEY_HEIGHT,height);// e.g. height=new Float(75) hints.put(ImageTranscoder.KEY_DOM_IMPLEMENTATION, impl.getDOMImplementation()); hints.put(ImageTranscoder.KEY_DOCUMENT_ELEMENT_NAMESPACE_URI,SVGConstants.SVG_NAMESPACE_URI); 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 ti=new TranscoderInput(uri) transcoder.transcode(ti, null); BufferedImage image = transcoder.getImage();
看起来batik的XMLAbstractTranscoder(http://svn.apache.org/repos/asf/xmlgraphics/batik/tags/batik-1_7/sources/org/apache/batik/transcoder/XMLAbstractTranscoder.java)版本1.7中有一些更新。
brccelvz3#
我尝试使用德文郡和John的建议,这几乎对我有效。我不得不做一些调整,如下所示,随时用途:
package com.corp.util; import static org.apache.batik.transcoder.SVGAbstractTranscoder.KEY_WIDTH; import static org.apache.batik.transcoder.XMLAbstractTranscoder.KEY_DOCUMENT_ELEMENT; import static org.apache.batik.transcoder.XMLAbstractTranscoder.KEY_DOCUMENT_ELEMENT_NAMESPACE_URI; import static org.apache.batik.transcoder.XMLAbstractTranscoder.KEY_DOM_IMPLEMENTATION; import static org.apache.batik.util.SVGConstants.SVG_NAMESPACE_URI; import static org.apache.batik.util.SVGConstants.SVG_SVG_TAG; import com.google.common.flogger.GoogleLogger; import org.apache.batik.anim.dom.SVGDOMImplementation; import org.apache.batik.transcoder.TranscoderException; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.TranscodingHints; import org.apache.batik.transcoder.image.ImageTranscoder; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.net.URL; import javax.annotation.concurrent.ThreadSafe; import javax.inject.Singleton; /** Loads SVG images from disk. See https://en.wikipedia.org/wiki/Scalable_Vector_Graphics. */ @Singleton @ThreadSafe public class SvgImageLoader { private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); /** * Reads in an SVG image file and return it as a BufferedImage with the given width and a height * where the original aspect ratio is preserved. * * @param url URL referencing the SVG image file, which is typically an XML file * @param width width in pixels the returned BufferedImage should be * * @return a valid image representing the SVG file * @throws IOException if the file cannot be parsed as valid SVG */ public static BufferedImage loadSvg(URL url, float width) throws IOException { SvgTranscoder transcoder = new SvgTranscoder(); transcoder.setTranscodingHints(getHints(width)); try { TranscoderInput input = new TranscoderInput(url.openStream()); transcoder.transcode(input, null); } catch (TranscoderException e) { throw new IOException("Error parsing SVG file " + url, e); } BufferedImage image = transcoder.getImage(); logger.atInfo().log("Read '%s' SVG image from disk requested with width=%.1f, sized as %dx%d pixels.", new File(url.getFile()).getName(), width, image.getWidth(), image.getHeight()); return image; } private static TranscodingHints getHints(float width) { TranscodingHints hints = new TranscodingHints(); hints.put(KEY_DOM_IMPLEMENTATION, SVGDOMImplementation.getDOMImplementation()); hints.put(KEY_DOCUMENT_ELEMENT_NAMESPACE_URI, SVG_NAMESPACE_URI); hints.put(KEY_DOCUMENT_ELEMENT, SVG_SVG_TAG); hints.put(KEY_WIDTH, width); return hints; } private static class SvgTranscoder extends ImageTranscoder { private BufferedImage image = null; @Override public BufferedImage createImage(int width, int height) { image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); return image; } @Override public void writeImage(BufferedImage img, TranscoderOutput out) {} BufferedImage getImage() { return image; } } }
8aqjt8rx4#
要避免传递dom参数,请执行以下操作:transcoder.setTranscodingHints((Map<?, ?>) hints);
transcoder.setTranscodingHints((Map<?, ?>) hints);
4条答案
按热度按时间eoxn13cs1#
这真的很简单,只是不是很直观。
需要扩展
ImageTranscoder
。在createImage
方法中,分配一个BufferedImage
,将其缓存为成员变量,并返回它。writeImage
方法为空。并且需要添加一个getter来检索BufferedImage
。它看起来像这样:
现在,要创建一个图像,您需要创建一个代码转换器的示例,并通过设置
TranscodingHints
将所需的宽度和高度传递给它。最后,您需要从一个TranscoderInput代码转换为一个null目标。然后调用代码转换器上的getter来获取图像。调用看起来像这样:
很简单,对吗?(是的,对。我只花了2个星期就想明白了。唉。)
kxkpmulp2#
我刚刚用蜡染-1.7遵循了德文郡的方法
然而,为了使它工作,我必须对hints对象进行以下添加:
看起来batik的XMLAbstractTranscoder(http://svn.apache.org/repos/asf/xmlgraphics/batik/tags/batik-1_7/sources/org/apache/batik/transcoder/XMLAbstractTranscoder.java)版本1.7中有一些更新。
brccelvz3#
我尝试使用德文郡和John的建议,这几乎对我有效。我不得不做一些调整,如下所示,随时用途:
8aqjt8rx4#
要避免传递dom参数,请执行以下操作:
transcoder.setTranscodingHints((Map<?, ?>) hints);