diegomura / react-pdf

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

Images throw error in view render prop #2637

Open SethThoburn opened 9 months ago

SethThoburn commented 9 months ago

Describe the bug Images throw an error in a view render prop.

To Reproduce

  1. Make a view with an image inside the render prop:
    <View
    render={({ pageNumber }) => (
    <Image
      style={{ width: 49, height: 49 }}
      src={
        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAAKYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIpQBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpdmZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoePPQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKcTNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jcW+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQjLYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII="
      }
    />
    )}
    />
  2. TypeError [Error]: Cannot read properties of undefined (reading 'width') at drawImage

The error is in this file: packages/render/src/primitives/renderImage.js Happens because image source isn't resolved. I'm new to this library, so couldn't fix it, but I think I see the issue after some digging. This file doesn't look into render functions: packages/layout/src/steps/resolveAssets.js

Expected behavior The image is displayed

SethThoburn commented 9 months ago

If you're in a pinch and need a workaround... you can add resolveAssets a second time to asyncCompose above resolvePagination. Theoretically, this wouldn't work correctly if the size of images was dependent on the page number, but that's not an issue for my use case.

This is in packages/layout/src/index.js. I applied the change with yarn patch-package.

const layout = asyncCompose(
  resolveZIndex,
  resolveOrigins,
  resolveAssets,
  resolvePagination,
  resolveTextLayout,
  resolvePercentRadius,
  resolveDimensions,
  resolveSvg,
  resolveAssets,
  resolveInheritance,
  resolvePercentHeight,
  resolvePagePaddings,
  resolveStyles,
  resolveLinkSubstitution,
  resolveBookmarks,
  resolvePageSizes,
  resolveYoga,
);
hect1c commented 9 months ago

I am also getting the same issue.

Tried doing the patch using pnpm but not sure I got it correctly also the issue is with the package @react-pdf/layout that is being referenced in @react-pdf/renderer. But this doesn't seem to be working correctly, probably due to the patch not being properly configured rather than the solution itself.

Is there any other solution? I will see if I can have some time to try and deep into the root problem.

SethThoburn commented 9 months ago

Yes, I spent a bit longer fighting with the configuration. You have to update your package.json so yarn applies the patch to dependencies of dependencies. I'm not certain how this works with pnpm.

"resolutions": {
    "@react-pdf/layout@^3.11.2": "patch:@react-pdf/layout@npm%3A3.11.2#~/.yarn/patches/@react-pdf-layout-npm-3.11.2-0ee6b2ccb4.patch"
  }
hect1c commented 9 months ago

Thanks it was actually quite easy with pnpm as I can see the changes reflected in the package in node_modules but it still wasn't working for me.

I did find an alternate solution that worked for me which is to use the url of the static file. I am using NextJS so accessing the files through the url is simple enough and will leave that there until this issue is fixed for local files.