Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jsPDF images are corrupted when using large, smartphone-captured jpegs #3318

Open
molorosh opened this issue Nov 15, 2021 · 10 comments · May be fixed by #3667
Open

jsPDF images are corrupted when using large, smartphone-captured jpegs #3318

molorosh opened this issue Nov 15, 2021 · 10 comments · May be fixed by #3667

Comments

@molorosh
Copy link

I've been trying to use the version 2.4.0 of jspdf to create a PDF containing images. However, the images are corrupted (basically just vertical stripes of grey).

The issues appears to be mainly affect jpegs that are captured from the camera directly. If you take a picture, crop it a little bit smaller and re-save it then it normally displays OK.

I've got a demo hosted at: https://upbeat-franklin-22e659.netlify.app/ that's written in knockout.

@MrRio
Copy link
Member

MrRio commented Nov 15, 2021 via email

@molorosh
Copy link
Author

samsung_note_9_cropped
samsung_note_9_direct

These are the files that were problematic for me. Both created on a Samsung Note 9 (Android). The raw image has an EXIF Orientation - Right top, the cropped version has an EXIF Orientation value of "0". Perhaps jsPDF doesn't know what to do with this alternative orientation values?

@EoinF
Copy link

EoinF commented Nov 19, 2021

I found a workaround for this. If you render it into a canvas first, the orientation of the image is fixed, and the distortion goes away.

var canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
context?.drawImage(img, 0, 0);
doc.addImage({ 
  imageData: canvas,
  ...

@Uzlopak
Copy link
Collaborator

Uzlopak commented Nov 19, 2021

I think we had a canvas fallback few versions ago. I think I removed it because canvas is not working in node and uses I think alot of memory.

@mrrusten
Copy link

mrrusten commented Dec 3, 2021

I found a workaround for this. If you render it into a canvas first, the orientation of the image is fixed, and the distortion goes away.

var canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
context?.drawImage(img, 0, 0);
doc.addImage({ 
  imageData: canvas,
  ...

I'm facing this same issue, and I have a link to image which I add like this:
doc.addImage(imageUrl, 'JPEG', 4, 4, newWidth, newHeight);

I do not understand how to use this workarounce. Would it be possible to explain a little bit more, if I might be so bold to ask?

@EoinF
Copy link

EoinF commented Dec 3, 2021

I'm facing this same issue, and I have a link to image which I add like this: doc.addImage(imageUrl, 'JPEG', 4, 4, newWidth, newHeight);

I do not understand how to use this workarounce. Would it be possible to explain a little bit more, if I might be so bold to ask?

In my example you need img which is a HTMLImageElement
You would get it like so:

const img = new Image();

img.onLoad = () => {
  // img is ready to be used in the code snippet I created previously
}
img.src = imageUrl;

Or maybe it's possible to use document.getByElementId if you already have it in an image tag. Not sure

@github-actions
Copy link

github-actions bot commented Mar 4, 2022

This issue is stale because it has been open 90 days with no activity. It will be closed soon. Please comment/reopen if this issue is still relevant.

@eugeniafranzoni
Copy link

The issue is still valid, as the canvas workaround causes extreme slowness

@HackbrettXXX HackbrettXXX reopened this Apr 4, 2022
@rnigro-rwb rnigro-rwb linked a pull request Nov 8, 2023 that will close this issue
@rnigro-rwb
Copy link

We've been hit with this issue as well, and have determined a cause and a fix. I have put through pull request (#3667) to address this issue.

The problem is with these markers used for getJpegInfo. It looks like it was intended to skip marker C4. It shows start-of-frame segments SOF5, SOF6, and SOF7 as having segment markers C4, C5, and C6 (and then oddly nothing on C7). But those segments actually have markers C5, C6, and C7.

This means getJpegInfo incorrectly tries to parse width/height data out of the DHT segment. Marker C4 is actually for a Huffman Table, a DHT segment (see ITU T.81).

The non-cropped image supplied by @molorosh (see below) has a C4 marker before the C0 marker. Because of this, the wrong sizing is determined. Removing the C4 marker from the list of markers allows it to find the C0 marker and get the correct size.

@Gambolico
Copy link

Any updates on the PR status?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants