3

我正在使用以下代码摄取 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。

更新:在没有任何答案或评论的情况下,我不得不编写自己的实现。这不是完全微不足道的,可能不是健壮的或最好的解决方案。我将其附加为答案-如果它有缺陷或可以改进,请发表评论。

4

1 回答 1

3

[回答自己的问题]

我认为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 双精度矩阵转换为 SVGtransform="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);
于 2012-12-18T10:38:48.943 回答