SVG в PNG с помощью Apache Batik, а затем прикрепить к PDF с помощью PDFBox без сохранения изображений

Итак, как следует из названия, я ищу способ превратить SVG в PNG с помощью Apache Batik, а затем прикрепить это изображение к файлу PDF с помощью PDFBox, фактически не создавая svg и png в любом месте.

В настоящее время у меня есть веб-форма с изображением SVG с выбираемыми частями. Когда форма отправлена, я беру часть «html» svg, что означает, что я сохраняю что-то вроде <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?


person D.V.D.    schedule 18.10.2018    source источник
comment
Может ли BATIK создать BufferedImage? Вы можете использовать его с LosslessFactory.   -  person Tilman Hausherr    schedule 18.10.2018
comment
Если нет, используйте ByteArrayOutputStream и ByteArrayInputStream.   -  person Tilman Hausherr    schedule 18.10.2018
comment
Другая альтернатива: stackoverflow.com/ вопросов/31718075/ Это было бы даже лучше, потому что сохранялась бы векторная графика, поэтому она отлично смотрелась бы при любом разрешении.   -  person Tilman Hausherr    schedule 19.10.2018
comment
@TilmanHausherr спасибо за предложения - думаю, теперь у меня все работает   -  person D.V.D.    schedule 19.10.2018


Ответы (2)



Основываясь на комментариях и ссылках, предоставленных D.V.D., я также решил эту проблему. Я просто хотел опубликовать простой, но полный пример для тех, кто захочет просмотреть его в будущем.

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();
        }
    }
}
person SharkDemon    schedule 21.10.2018