diegomura / react-pdf

📄 Create PDF files using React
https://react-pdf.org
MIT License
14.34k stars 1.13k forks source link

Image rendering broken for some image since 3.2.0 #2656

Closed nikgraf closed 2 months ago

nikgraf commented 3 months ago

Describe the bug

We are using react-pdf with 3.1.7. After upgrading @react-pdf/renderer to 3.3.8 we noticed image rendering was broken in some cases. We identified that it broke between the version 3.1.7 and 3.2.0.

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

  1. Go to https://react-pdf.org/repl
  2. Paste in this code:
const Quixote = () => (
  <Document>
    <Page style={styles.body}>
      <Image
        style={styles.image}
        src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@2x.png"
      />
      <Image
        style={styles.image}
        src="https://posts-swat-io.s3.eu-central-1.amazonaws.com/3e07cc90110d699d18c2793766340a97b9948b09.jpg"
      />
    </Page>
  </Document>
);

const styles = StyleSheet.create({
  body: {
    paddingTop: 35,
    paddingBottom: 65,
    paddingHorizontal: 35,
  },
  image: {
    marginVertical: 15,
    marginHorizontal: 100,
  },
});

ReactPDF.render(<Quixote />);

Expected behavior The second image should also be rendered. When opened in the browser it renders fine.

DanielWahl commented 3 months ago

I have the same problem with .jpg images. They are shown in the PDFViewer in Chrome, but not in Safari. After downloading the PDF from the viewer, the no .jpg-images are shown, only .png-images.

Has anyone found a fix for it?

mesh-newbie commented 3 months ago

Same same here. Thought I was going mad. Workaround was to temporarily change images to png. :-(

casperandreassen commented 3 months ago

Same for me.

A PDF with images will show the images in chrome webview, but the images will disappear in safari or preview (mac). They cannot be opened in Adobe Reader at all.

Have found that it is only png images that will work, we convert all formats to png with sharp and then give them to react-pdf as a buffer. All other methods seems to create a corrupt pdf file.

joelybahh commented 3 months ago

Any progress here? I've found after running jpegs through squoosh, even if the output isn't a smaller file size, the image all of a sudden starts to load, otherwise we see these hard to action logs:

Unknown version 17
Unknown version 17
IFDHandler is not defined

These images are jpg rendered serverside. What is the best way to deal with the seemingly fragile images for react-pdf? Is it just png only for now, is there an old version where this wasn't an isssue?

joelybahh commented 3 months ago

Extending the above how do we handle these silent errors, we can't really catch or action these, they are just logs and require manually adressing each image.

mesh-newbie commented 3 months ago

Same for me.

A PDF with images will show the images in chrome webview, but the images will disappear in safari or preview (mac). They cannot be opened in Adobe Reader at all.

Have found that it is only png images that will work, we convert all formats to png with sharp and then give them to react-pdf as a buffer. All other methods seems to create a corrupt pdf file.

Perhaps coincidental, but when attempting to print said pdf to a xerox machine using a locally embedded font (e.g Montserrat), the printer spits the dummy. It crashes, attempts to print the error message on the page, then swiftly ejects at force.

joelybahh commented 3 months ago

Extending the above how do we handle these silent errors, we can't really catch or action these, they are just logs and require manually adressing each image.

Sorry, the above errors are thrown if you have a no height view with a jpeg inside, this was an error on my end, I worked around jpeg images not showing up on mac/adobe reader by just fetching all the image buffers from URL, and using sharp on the serverside to parse them all to pngs, and use the buffer instead of the URL.

const convertImageToPNGBuffer = async (blobUrl: string) => {
    const response = await fetch(blobUrl);
    const imageBuffer = await response.buffer();

    return sharp(imageBuffer)
        .resize({
            fit: "contain",
            width: 700,
        })
        .png({
            quality: 80,
            compressionLevel: 9,
        })
        .toBuffer();
};

This only works if your doing this in serverside as I believe sharp is only available, but other client side conversion exist with a similar idea, this is my workaround for right now.

h0wXD commented 3 months ago

I have noticed the same, after upgrading the package from 3.0.1, there seems to be inconsistent behavior where the logs are spammed with the error IFDHandler is not defined upon loading images. This hasn't occurred prior to upgrading

aldipower commented 3 months ago

Can confirm. Same here. Jpgs are not rendering in some viewers for example in Envice (Linux), but in Firefox it does.

PelosiTech commented 3 months ago

Add this

"resolutions": { "@react-pdf/layout": "3.6.4", "@react-pdf/textkit": "4.3.0", "@react-pdf/image": "2.2.2", "@react-pdf/pdfkit": "3.1.2" }

Will fix a lot of issues for everyone.

krzysztof-stanislawski commented 3 months ago

I'm using ghostscript to downsize generated PDFs. Using jpeg images in tags throws error while resizing in ghostscript. I am getting pdf without jpeg images then. It's also not rendering them before gs.

Ghostscript error: 
The following errors were encountered at least once while processing this file:
        object lacks an endobj
        error executing PDF token

   **** This file had errors that were repaired or ignored.
   **** The file was produced by:
   **** >>>> react-pdf <<<<
   **** Please notify the author of the software that produced this
   **** file that it does not conform to Adobe's published PDF
   **** specification.
jason-migz commented 3 months ago

Guys, we can try https://github.com/diegomura/react-pdf/pull/2646#issuecomment-2001974202 as a Temporary Fix.

joelybahh commented 2 months ago

Guys, we can try #2646 (comment) as a Temporary Fix.

I tried updating the dependancies specifically, and even after yarn install its still rendering with blank images on mac/adobe, were you referring to the dependencies part of that comment, or the download and workspaces symlinked approach? @jason-migz (We are using yarn as an FYI)

jason-migz commented 2 months ago

Guys, we can try #2646 (comment) as a Temporary Fix.

I tried updating the dependancies specifically, and even after yarn install its still rendering with blank images on mac/adobe, were you referring to the dependencies part of that comment, or the download and workspaces symlinked approach? @jason-migz (We are using yarn as an FYI)

@joelybahh for the meantime, use file import in package.json, yes you can use yarn, I am using yarn too. dependencies or resolutions will not work, i already tried it.

joelybahh commented 2 months ago

@jason-migz, thanks. I tried the files approach but had some issues. We're running from a monorepo, which might be where the added issue is coming from, I'll try that approach again later today. Thank you. I appreciate the effort in providing this workaround