Using rotate for images leads to blank pdf with pdfkit

Issue

I have asked the question on the repository directly, but in my experience SO is more reactive.

Hey there,

I am trying to create a pdf from photos using pdfkit.
Depending on whether an image is in landscape or portait mode, I want to turn the image around.

This basically means the following (in typescript) :

function toPostscriptPoint(mm: number) {
    return mm * 2.8346456693;
}
const document = new PDFDocument({
    size: [toPostscriptPoint(156), toPostscriptPoint(106)],
});

document.pipe(fs.createWriteStream('output.pdf'));

document.save();
document.rotate(90);
document.image(
            'photos/sample.jpeg',
            { width: toPostscriptPoint(150), fit: [toPostscriptPoint(150), toPostscriptPoint(100)] });
    document.restore();

document.end();

What happens though is that the pdf renders completely white. I do see however that something is happening, because the pdf has the size of the input image.

Is rotation for images not supported? What would be possible alternatives? I would like to avoid having to rewrite my files before putting them in the pdf.

Thanks

Solution

Alright, after investigation, I can answer my own question :).

I could see that the images were in the pdf somehow because of the size of the file so I dived deeper.

What happened was that the image was rendered out of the viewport. This was due to multiple things:
* By default, the origin of a page after rotation in pdfkit is the center of the page! ( See the doc for more info)
* The origin is rotated together with the transformation.
* The x and y in the image method are actually inverted.

So after getting all this right, the following code shows the image as expected :

function toPostscriptPoint(mm: number) {
    return mm * 2.8346456693;
}
const document = new PDFDocument({
    size: [toPostscriptPoint(156), toPostscriptPoint(106)],
});

document.pipe(fs.createWriteStream('output.pdf'));

document.save();
document.rotate(90, {origin : [0, 0]});
document.image(
            'photos/sample.jpeg',
            toPostscriptPoint(0),
            toPostscriptPoint(-150),
            { width: toPostscriptPoint(150), height: toPostscriptPoint(100) });
    document.restore();

document.end();

Note the :

  • origin argument in the rotation
  • toPostscriptPoint(-150) actually takes into account the position of the origin, and corresponds to the X axis.

Hope that helps some later on :).

Answered By – jlengrand

Answer Checked By – Pedro (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.