使用 Apache Batik 将 SVG 转换为 PNG,然后使用 PDFBox 附加到 PDF 而不保存图像

SVG to PNG with Apache Batik then attach to PDF with PDFBox without saving images

所以正如标题所说,我正在寻找一种方法,使用 Apache Batik 将 SVG 转换为 PNG,然后使用 PDFBox 将此图像附加到 PDF 文件,而无需在任何地方实际创建 svg 和 png。

目前我有一个 Web 表单,其中包含 SVG 图像以及其中的可选部分。 提交表单后,我采用 svg 的 "html" 部分,这意味着我将 <svg bla bla> <path bla bla/></svg> 之类的内容保存在字符串中,然后 Spring 用于在给定文件夹中创建“.svg”文件,然后 Batik 在同一文件夹中创建一个 PNG 文件,然后 PDFBox 将其附加到 PDF - 这工作正常(代码如下)。

//Get the svg data from the Form and Create the svg file
String svg = formData.getSvg();
File svgFile = new File("image.svg");
BufferedWriter writer = new BufferedWriter(new FileWriter(svgFile));
writer.write(svg);
writer.close(); 
// Send to Batik to turn to PNG
PNGTranscoder pngTranscode = new PNGTranscoder();
File svgFile = new File("image.svg");
InputStream in = new FileInputStream(svgFile);
TranscoderInput tIn = new TranscoderInput(in);
OutputStream os = new FileOutputStream("image.png");
TranscoderOutput tOut = new TranscoderOutput(os)
pngTranscode .transcode(tIn , tOut);
os.flush();
os.close();
//Send to PDFBox to attach to pdf
File pngfile = new File("image.png");
String path = pngfile.getAbsolutePath();                    
PDImageXObject pdImage = PDImageXObject.createFromFile(path, pdf);
PDPageContentStream contents = new PDPageContentStream(pdf, pdf.getPage(1));
contents.drawImage(pdImage, 0, pdf.getPage(1).getMediaBox().getHeight() - pdImage.getHeight()); 
contents.close();

如您所见,有很多文件和东西(需要稍微整理一下),但是是否可以在 运行 上执行此操作而无需创建和不断获取 svg和 png 文件?

鉴于评论中的建议,我选择使用 ByteArrayOutputStream、ByteArrayInputStream、BufferedImage 和 LosslessFactory。它比保存慢一点(如果你在调试中经历它,因为 BufferedImage 在创建图像之前似乎先去度假)。 我发现使用的来源是:How to convert SVG into PNG on-the-fly and

byte[] streamBytes = IOUtils.toByteArray(new ByteArrayInputStream(formData.getSvg().getBytes()));
PNGTranscoder pngTranscoder = new PNGTranscoder();
ByteArrayOutputStream os = new ByteArrayOutputStream();                  
pngTranscoder.transcode(new TranscoderInput(new ByteArrayInputStream(streamBytes)), new TranscoderOutput(os));
InputStream is = new ByteArrayInputStream(os.toByteArray());
BufferedImage bim = ImageIO.read(is);
PDImageXObject pdImage = LosslessFactory.createFromImage(pdf, bim);
PDPageContentStream contents = new PDPageContentStream(pdf, pdf.getPage(1));
contents.drawImage(pdImage, 0, pdf.getPage(1).getMediaBox().getHeight() - pdImage.getHeight()); 
contents.close();

根据 D.V.D. 提供的评论和链接,我也解决了这个问题。我只是想 post 这个简单但完整的例子,供以后想复习的任何人使用。

public class App {

    private static String OUTPUT_PATH = "D:\so52875145\output\PdfWithPngImage.pdf";

    public static void main(String[] args) {

        try {
            // obtain the SVG source (hardcoded here, but the OP would obtain the String from form data)
            byte[] svgByteArray = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><polygon points=\"200,10 250,190 160,210\" style=\"fill:lime;stroke:purple;stroke-width:1\" /></svg>".getBytes();
            System.out.println("Converted svg to byte array...");

            // convert SVG into PNG image
            PNGTranscoder pngTranscoder = new PNGTranscoder();
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            pngTranscoder.transcode(new TranscoderInput(new ByteArrayInputStream(svgByteArray)), new TranscoderOutput(os));
            System.out.println("Transcoded svg to png...");

            // create PDF, and add page to it
            PDDocument pdf = new PDDocument();
            pdf.addPage(new PDPage());

            // generate in-memory PDF image object, using the transcoded ByteArray stream
            BufferedImage bufferedImage = ImageIO.read( new ByteArrayInputStream(os.toByteArray()) );
            PDImageXObject pdImage = LosslessFactory.createFromImage(pdf, bufferedImage);
            System.out.println("Created PDF image object...");

            // write the in-memory PDF image object to the PDF page
            PDPageContentStream contents = new PDPageContentStream(pdf, pdf.getPage(0));
            contents.drawImage(pdImage, 0, 0);
            contents.close();
            System.out.println("Wrote PDF image object to PDF...");

            pdf.save(OUTPUT_PATH);
            pdf.close();
            System.out.println("Saved PDF to path=[" + OUTPUT_PATH + "]");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}