我正在使用以下代码摄取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兼容。
更新:在没有任何答案或评论的情况下,我不得不编写自己的实现。这不是完全无足轻重的,可能不是强大的或最好的解决方案。我将其作为答案附加 - 请评论是否有缺陷或可以改进。
答案 0 :(得分:2)
[回答自己的问题]
我认为java.awt.Image
是BufferedImage
,因为它有适当的方法。在目前的情况下,这是有效的(到目前为止)。
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);