react-pdf icon indicating copy to clipboard operation
react-pdf copied to clipboard

Images in pdf are rotated by 90degs

Open Ballonek opened this issue 2 years ago • 5 comments

Describe the bug Images in pdf are rotated by 90degs, i use @react-pdf/renderer in nodejs express server and generate Pdf reports. Most of the time, the images rotate correctly. And they appear correctly in the image tag on the web. Could you help me how to fix it? Image is from aws link source.

To Reproduce Steps to reproduce the behavior including code snippet (if applies):

  1. I dont really know when this happens

Expected behavior I expect images to be rotated as it is in web view

Screenshots IN PDF: Snímek obrazovky 2022-06-01 v 9 45 26

IN WEB IMG TAG: Snímek obrazovky 2022-06-01 v 9 45 34

Desktop (please complete the following information):

  • OS: [MacOS, Windows]
  • Server Node.js, Express - locally and heroku too
  • React-pdf version [2.1.2]

Ballonek avatar Jun 01 '22 07:06 Ballonek

I think that's something specific to that image. Can you share it so I tried replicating it?

diegomura avatar Jun 01 '22 14:06 diegomura

Hello, I am experiencing a similar issue, and have to use transform:rotate in the inline styling in order to get the image looking normal.

Unfortunately, not all of the images need to be rotated back into place, so applying this styling does not always work as intended.

mp-datafleet avatar Aug 19 '22 17:08 mp-datafleet

To give more detail @diegomura ...

I'm pulling the images from Firebase Storage. When rendering an image on a webpage, or simply viewing the image directly in the browser via its Firebase Storage url, the image displays as it should (ie, rotated the way it was when it was uploaded to Firebase Storage).

However, when passing the URL along to a component that uses React-PDF, for some reason, the same image will render rotated 90* when the PDF is created.

mp-datafleet avatar Aug 23 '22 15:08 mp-datafleet

@mp-datafleet @diegomura Hi, I let the problem lie. The last thing we found was that it was caused by exif data. When we rotated the image in the appropriate program that can rotate exif image data, the image displayed as it should. It looks like it was using the css property image-orientation: from-image;. But I'm not sure because I didn't troubleshoot it anymore after that.

Ballonek avatar Aug 23 '22 18:08 Ballonek

@mp-datafleet @diegomura Hi, I let the problem lie. The last thing we found was that it was caused by exif data. When we rotated the image in the appropriate program that can rotate exif image data, the image displayed as it should. It looks like it was using the css property image-orientation: from-image;. But I'm not sure because I didn't troubleshoot it anymore after that.

@Ballonek thanks for the reply.

Unfortunately, we're still unable to figure this out, so we'll need to figure out an alternative to this package.

mp-datafleet avatar Aug 30 '22 18:08 mp-datafleet

2022-10-27_14-21 2022-10-27_14-21_1 2022-10-27_14-21_2 IMG_7318 IMG_7316 IMG_7315

Dima9119708 avatar Oct 27 '22 11:10 Dima9119708

Has there any solution come for this problem ?

ShahriarSaleque avatar Dec 01 '22 13:12 ShahriarSaleque

Bump... this issue is preventing us from going live.

margulesl avatar Apr 27 '23 20:04 margulesl

@diegomura any update on this issue?

margulesl avatar May 02 '23 20:05 margulesl

I had the same issue and I fixed manually each rotated image on PDF on Paint by editing (just a copy paste) and saving them. All my rotated images on PDF came from my phone. I took some of them in landscape and rotated them in portrait on my phone. I think the issue comes from the image and react-pdf/rendrer is not able to know what is the right wanted rotation

CheongLoic avatar May 08 '23 21:05 CheongLoic

Hello everyone,

I've used react-pdf/renderer in a professional project and ran into the same issue.

I was able to find a workaround using a 3rd party library.

I'll see if I can elaborate more later and possibly work on a PR.

mpieciak18 avatar May 09 '23 14:05 mpieciak18

@mpieciak18 care to elaborate more?

margulesl avatar Jun 07 '23 20:06 margulesl

@margulesl Sorry for the delay. Below I'll elaborate how I've been able to work around this issue. Hopefully someone will be able to take my solution and somehow incorporate into this library.

First, prior to the the PDF component being rendered, I fetch the image from the URL that is going to be passed to an <Image> within the PDF (typically, this is done in a parent component containing the child component rendering the PDF). The URL of the image is usually assigned to the key of an object that contains other data about the <Image> to be rendered.

From there, I use the exifreader library to extract the exif data from the fetched image and assign it to the image's object as a key:val pair.

import ExifReader from 'exifreader';

const imageObj = { 
    url: //,
    ...
}

const res = await fetch(imageObj.url);
const blob = await res.blob();
const arrBuff = await blob.arrayBuffer();
const tags = ExifReader.load(arrBuff);
imageObj.exif = tags;

From there, the imageObj is passed to the component rendering the PDF and is used to determine how the image should be rotated: 0*, 90*, 180*, or 270*. Note the marginLeft and marginTop rules are just arbitrary values to compensate how much the image shifts when it is rotated. The marginTop in imgRotOne and imgRotThree aren't necessary: they are just how things needed to be styled in my specific case.

const styles = StyleSheet.create({
    imgRotOne: {
	    width: '100%',
	    marginTop: '-15px',
    },
    imgRotSix: {
	    transform: 'rotate(90deg)',
	    width: '100%',
	    marginLeft: '-33px',
	    marginTop: '18px',
    },
    imgRotThree: {
	    transform: 'rotate(180deg)',
	    width: '100%',
	    marginTop: '-15px',
    },
    imgRotEight: {
	    transform: 'rotate(270deg)',
	    width: '100%',
	    marginLeft: '-33px',
	    marginTop: '18px',
    },
});

...

let style;
const rotVal = imageObj.exif?.Orientation?.value;
if (rotVal == 1 || rotVal == undefined) {
        style = styles.imgRot1;
} else if (rotVal == 3) {
	style = styles.ImgRot3;
} else if (rotVal == 6) {
	style = styles.imageRot6;
} else if (rotVal == 8) {
	style = styles.imageRot8;
}

...

<Image style={style} src={imageObj.url} />

Since this involves downloading the image ahead of time, it's not the most efficient because the image then needs to be downloaded again as the library renders the <Image> component, so it'd be nice if there was a way to incorporate this into the library itself.

mpieciak18 avatar Aug 02 '23 14:08 mpieciak18

@diegomura Kindly see above.

mpieciak18 avatar Aug 08 '23 19:08 mpieciak18

Facing the same issue with dynamic user provided images. Unfortunately, they will be displayed in a dynamic size in a dynamic grid, so the workaround provided will make things a lot more complicated then needed. Is this an issue with react-pdf only or may be even deeper in pdfkit?

Thank you all!

Example image below (taken on iPhone, as far as I can tell no rotation applied) location

nikischin avatar Sep 04 '23 22:09 nikischin

I ended up rewriting my PDF generation in a backend library. React PDF is nice, but it's not ready for production level software.

margulesl avatar Sep 06 '23 12:09 margulesl