2012-12-17 53 views
2

我攝取的圖像AWT(從PDF,通過PDFBox的)用下面的代碼:轉換AWT圖像SVG圖片

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。我一直用它產生的形式

<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類產生類似的SVG的蠟染庫。我是否需要將AffineTransformation應用於數據,如果是這樣的話?

我希望能指出適當的(F/OSS)方法或庫可以做到這一點。數據應該是內聯的(如上例)和XML兼容。

更新:在沒有任何答案或評論我不得不寫我自己的實現。這不是微不足道的,可能不健壯或最好的解決方案。我附上它作爲答案 - 請評論它是否有缺陷或可以改進。

回答

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