将AWT图像转换为SVG图像

时间:2012-12-17 11:28:56

标签: java image svg awt

我正在使用以下代码摄取AWT图像(从PDF到PDFBox):

private java.awt.Graphics2D graphics;
public void drawImage(java.awt.Image awtImage, java.awt.geom.AffineTransform at) {
    graphics.setComposite(getGraphicsState().getStrokeJavaComposite());
    graphics.setClip(getGraphicsState().getCurrentClippingPath());
    graphics.drawImage( awtImage, at, null );
}

并希望捕获/输出图像为SVG。我一直在使用生成

形式的svg的Batik库
    <image x="0" y="0" transform="matrix(0.144,0,0,0.1439,251.521,271.844)" 
clip-path="url(#clipPath2)" width="1797" xlink:href="data:image/png;
base64,iVBORw0KGgoAAAANSUhEUgAABwUAAAV4CAMAAAB2DvLsAAADAFBMVEX////+/v56 
enpWVlZbW1taWlpZWVnHx8eRkZFVVVWMjIysrKxXV1dYWFhqamr5+fnMzMxeXl7c 
3NyUlJR/f3+3t7cAAACGhob29vYpKSliYmJPT083Nzf8/PyBgYENDQ3s7OwwMDD1 
    ...
    RERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERE 
RPQP/R8CiIK+y8Q6KQAAAABJRU5ErkJggg==" height="1400"
 preserveAspectRatio="none" stroke-width="0" xmlns:xlink="http://www.w3.org/1999/xlink"/>

我有自己的SVG库,想要在我的SVGImage类中添加方法来生成类似的东西。我是否需要将AffineTransformation应用于数据,如果是这样的话?

我很高兴能够指出适当的(F / OSS)方法或可以做到这一点的库。数据应该是内联的(如上例所示)和XML兼容。

更新:在没有任何答案或评论的情况下,我不得不编写自己的实现。这不是完全无足轻重的,可能不是强大的或最好的解决方案。我将其作为答案附加 - 请评论是否有缺陷或可以改进。

1 个答案:

答案 0 :(得分:2)

[回答自己的问题]

我认为java.awt.ImageBufferedImage,因为它有适当的方法。在目前的情况下,这是有效的(到目前为止)。

SVG需要图像的MIME类型(例如“image/png”)。 ImageIO需要一种类型,例如“PNG”。 mimeType2ImageTypeMap映射这些。 Base64编解码器取自Xerces,但有很多。 DOM实现是XOM,属性构造为xlink提供命名空间

    public class SVGImage extends xom.nu.Element {
    private static final String DATA = "data";
    private static final String BASE64 = "base64";
    public static final String IMAGE_PNG = "image/png";
    public static final String PNG = "PNG";

    private static final String XLINK_PREF = "xlink";
    private static final String HREF = "href";
    private static final String XLINK_NS = "http://www.w3.org/1999/xlink";

        public void readImageData(BufferedImage bufferedImage, String mimeType) {
    String type = mimeType2ImageTypeMap.get(mimeType);
    if (type == null) {
        throw new RuntimeException("Cannot convert mimeType: "+mimeType);
    }
    double x = bufferedImage.getMinX();
    double y = bufferedImage.getMinY();
    double height = bufferedImage.getHeight();
    double width = bufferedImage.getWidth();
    this.setX(x);
    this.setY(y);
    this.setWidth(width);
    this.setHeight(height);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try {
        ImageIO.write(bufferedImage, type, baos);
    } catch (IOException e) {
        throw new RuntimeException("Cannot read image", e);
    }
    byte[] byteArray = baos.toByteArray();
    String base64 = Base64.encode(byteArray);
    String attValue = DATA+":"+mimeType+";"+BASE64+","+base64;
    this.addAttribute(new Attribute(XLINK_PREF+":"+HREF, XLINK_NS, attValue));
    }
}

上面的代码处理了一个测试用例,所以我很乐观它会扩展到大型图像和其他MIME类型,但还没有测试过它们。

是:我必须应用仿射变换。我已经有了实用程序,它将3 * 2矩阵的双精度转换为SVG transform="matrix(...)"属性。所以我的最终代码是:

Transform2 t2 = new Transform2(at);              // converts matrix syntax
BufferedImage bImage = (BufferedImage) awtImage;
SVGImage svgImage = new SVGImage();
svgImage.setTransform(t2);
svgImage.readImageData(bImage, SVGImage.IMAGE_PNG);