Converting PDF to multipage tiff (Group 4)

后端 未结 5 1471
不思量自难忘°
不思量自难忘° 2020-12-02 00:32

I\'m trying to convert PDFs as represented by the org.apache.pdfbox.pdmodel.PDDocument class and the icafe library (https://github.com/dragon66/icafe/) to a multipage tiff w

5条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-02 01:16

    Since some dependencies used by solutions for this problem looks not maintained. I got a solution by using latest version (2.0.16) pdfbox:

    ByteArrayOutputStream imageBaos = new ByteArrayOutputStream();
    ImageOutputStream output = ImageIO.createImageOutputStream(imageBaos);
    ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next();
    
    try (final PDDocument document = PDDocument.load(new File("/tmp/tmp.pdf"))) {
    
                PDFRenderer pdfRenderer = new PDFRenderer(document);
    
                int pageCount = document.getNumberOfPages();
    
                BufferedImage[] images = new BufferedImage[pageCount];
                // ByteArrayOutputStream[] baosArray = new ByteArrayOutputStream[pageCount];
    
                writer.setOutput(output);
    
                ImageWriteParam params = writer.getDefaultWriteParam();
    
                params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    
                // Compression: None, PackBits, ZLib, Deflate, LZW, JPEG and CCITT
                // variants allowed
                params.setCompressionType("Deflate");
    
                writer.prepareWriteSequence(null);
    
                for (int page = 0; page < pageCount; page++) {
                    BufferedImage image = pdfRenderer.renderImageWithDPI(page, DPI, ImageType.RGB);
                    images[page] = image;
                    IIOMetadata metadata = writer.getDefaultImageMetadata(new ImageTypeSpecifier(image), params);
                    writer.writeToSequence(new IIOImage(image, null, metadata), params);
                    // ImageIO.write(image, "tiff", baosArray[page]);
                }
    
                System.out.println("imageBaos size: " + imageBaos.size());
                // Finished write to output
    
                writer.endWriteSequence();
    
                document.close();
            } catch (IOException e) {
                e.printStackTrace();
                throw new Exception(e);
            } finally {
                // avoid memory leaks
                writer.dispose();
            }
    

    Then you may using imageBaos write to your local file. But if you want to pass your image to ByteArrayOutputStream and return to privious method like me. Then we need other steps.

    After processing is done, the image bytes would be available in the ImageOutputStream output object. We need to position the offset to the beginning of the output object and then read the butes to write to new ByteArrayOutputStream, a concise way like this:

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    long counter = 0; 
            while (true) {
                try {
                    bos.write(ios.readByte());
                    counter++;
                } catch (EOFException e) {
                    System.out.println("End of Image Stream");
                    break;
                } catch (IOException e) {
                    System.out.println("Error processing the Image Stream");
                    break;
                }
            }
    return bos
    

    Or you can just ImageOutputStream.flush() at end to get your imageBaos Byte then return.

提交回复
热议问题