jsPDF icon indicating copy to clipboard operation
jsPDF copied to clipboard

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

Open molorosh opened this issue 3 years ago • 10 comments

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.

molorosh avatar Nov 15 '21 10:11 molorosh

Is it a JPEG or JPEG2000 / other variation?

On Mon, 15 Nov 2021 at 10:58, Howard G Ricketts @.***> wrote:

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.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/parallax/jsPDF/issues/3318, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAALTMYDONLQFICZJYDSLODUMDRULANCNFSM5IBMH5GQ .

-- James Hall Director

Parallax

Office: +44 113 322 6477 Mobile: +44 7894 950320 Web: https://parall.ax

• Northern Tech 100 - Four Years Running • Top 50 Digital Agencies in the North - Four Years Running • A Yorkshire & Humberside Top 50 Tech Firm • One of the Top 25 Fastest-Growing Tech Businesses in Leeds • ISO 9001 & ISO 27001 Certified

Registered office: Parallax, The Elbow Rooms, 64 Call Lane, Leeds, LS1 6DT Registered in England no. 07430032 VAT No. 101 3405 84

MrRio avatar Nov 15 '21 12:11 MrRio

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?

molorosh avatar Nov 15 '21 15:11 molorosh

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,
  ...

EoinF avatar Nov 19 '21 17:11 EoinF

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.

Uzlopak avatar Nov 19 '21 17:11 Uzlopak

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?

mrrusten avatar Dec 03 '21 12:12 mrrusten

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

EoinF avatar Dec 03 '21 13:12 EoinF

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.

github-actions[bot] avatar Mar 04 '22 02:03 github-actions[bot]

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

eugeniafranzoni avatar Mar 22 '22 16:03 eugeniafranzoni

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.

rnigro-rwb avatar Nov 08 '23 17:11 rnigro-rwb

Any updates on the PR status?

Gambolico avatar Feb 21 '24 09:02 Gambolico