3

次のコードを使用して、(PDF から PDFBox を介して) AWT 画像を取り込みます。

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.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 行列を 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 に答える