OpenPDF icon indicating copy to clipboard operation
OpenPDF copied to clipboard

Setting page size doesn't take effect until new page

Open tbessie opened this issue 3 years ago • 5 comments

Describe the bug When I create a new Document and add images to it, I set the page size for each image received before adding the image. However, the page size I set doesn't appear to take effect until the next page. This worked differently in the older version of iText we ported this from.

To Reproduce

    /**
     * Convert TIFF to PDF.
     * Used for processing incoming Fax data.
     */
    public byte[] convertTIFFToPDF(byte[] originalBytes) throws Throwable {

        // Make sure input is non-null
        originalBytes = (originalBytes == null) ? new byte[0] : originalBytes;

        Document document = new Document();
        ByteArrayOutputStream outfile = new ByteArrayOutputStream();
        ByteArrayInputStream bais = null;

        PdfWriter writer = PdfWriter.getInstance(document, outfile);
        writer.setStrictImageSequence(true);
        document.open();

        bais = new ByteArrayInputStream(originalBytes);

        ImageInputStream iis = ImageIO.createImageInputStream(bais);

        if (iis == null) {
            throw new IllegalStateException("Cannot create ImageInputStream for bytes");
        }

        ImageReader reader = getTIFFImageReader();
        reader.setInput(iis);
        int pages = reader.getNumImages(true);
        for (int imageIndex = 0; imageIndex < pages; imageIndex++) {
            BufferedImage bufferedImage = reader.read(imageIndex);
            Image image = Image.getInstance(bufferedImage, null, false);
            if (image.getDpiX() > 0 && image.getDpiY() > 0) {
                image.scalePercent(7200f / image.getDpiX(), 7200f / image.getDpiY());
            }

            document.setPageSize(new Rectangle(image.getScaledWidth(), image.getScaledHeight()));

            image.setAlignment(Image.MIDDLE);

            /* ---> PROBLEM HERE: THIS IMAGE APPEARS IN PDF AS DEFAULT PAGE SIZE (A4)
             * FOR FIRST PAGE INSTEAD OF PAGE SIZE WE JUST SET.  IN THIS LOOP, PAGE SIZE SEEMS
             * TO LAG FROM LAST PAGE SIZE SET.
             */
            /* This worked in an older version of iText, but not in current version of OpenPDF */
            document.add(image);

            document.newPage();
        }
    }

    private static ImageReader getTIFFImageReader() {

        Iterator<ImageReader> imageReaders = ImageIO.getImageReadersByFormatName("TIFF");

        if (!imageReaders.hasNext()) {
            throw new UnsupportedOperationException("No TIFF Reader found");
        }

        return imageReaders.next();
    }

Expected behavior Page size applies to current page, not next page.

Screenshots

System (please complete the following information):

  • OS: MacOS & Linux
  • Used Font: N/A

Additional context Add any other context about the problem here.

tbessie avatar May 25 '22 23:05 tbessie

Hi, can I work on this issue?

Brooklyn-0 avatar May 26 '22 08:05 Brooklyn-0

Hi, can I work on this issue?

Not sure if you're asking me, or someone who's in charge of the project. :-)

If you do, in any case, when I stepped through what's happening, I suspected the various listener events that are being fired and how they are responded to. Perhaps they are being ignored for page size change for current page. I don't know what the listeners are doing, though, as I didn't step into them.

tbessie avatar May 26 '22 19:05 tbessie

NOTE: I also noticed that the default MediaBox value per PDF page is the same as the resolution of the image that page contains. In the iText version we were using, the default value is A4 (which appears the default pagesize overall). I'm not sure if this is a bug in the old iText library or a bug in OpenPDF - probably debateable.

tbessie avatar May 27 '22 21:05 tbessie

It looks like this (and associated behavior) is the culprit, from PdfDocument:

public boolean setPageSize(Rectangle pageSize) {
    if (this.writer != null && this.writer.isPaused()) {
        return false;
    } else {
        this.nextPageSize = new Rectangle(pageSize);
        return true;
    }
}

tbessie avatar May 27 '22 22:05 tbessie

hi tbessie, i moved document.open() after document.setPageSize, it works fine.

bluesunxp avatar Nov 01 '23 08:11 bluesunxp