react-pdf
react-pdf copied to clipboard
Allow to use Blob as the Image source
Is your feature request related to a problem? Please describe. On web contexts it is more handy to be able to use a Blob as the data source. Even on modern versions of Node and other runtimes like Deno, have implemented this Web API.
A common use case would be taking an image from a canvas:
<Image
src={() => {
const canvas = document.createElement('canvas')
renderQR(canvas, "Hello world")
// Now what?
}}
/>
A naive approach would be creating a Data url with canvas.toDataURL()
. But it is known to have some drawbacks.
So. Why don't create a Blob and use URL.createObjectUrl?
<Image
src={async () => {
const canvas = document.createElement("canvas");
renderQR(canvas, "Hello world");
const blob = await new Promise((resolve, reject) =>
canvas.toBlob((blob) => {
if (blob) {
return resolve(blob);
} else {
return reject(new Error("couldn't create Blob"));
}
})
);
return URL.createObjectUrl(blob);
}}
/>
Now we have a worse problem. There is a memory leak!. Since we are not calling URL.revokeObjectUrl to release the resources. We could workaround it with a useRef
and a useEffect
, but the code becomes very verbose and hard to follow.
Describe the solution you'd like Allow to pass a Blob as the source for images, instead of only allowing Buffer, which is a Node-only API (we could polyfill it on other environments, but it just doesn't feels natural)
It would allow something like:
<Image
src={() => {
const canvas = document.createElement("canvas");
renderQR(canvas, "Hello world");
return new Promise((resolve, reject) =>
canvas.toBlob((blob) => {
if (blob) {
return resolve(blob);
} else {
return reject(new Error("couldn't create Blob"));
}
})
);
}}
/>
As a sidenote I think this can be a starting point to reduce the dependencies on node specific APIs and replacing them by Web APIs, like Web Streams, the Fetch API, etc.
Describe alternatives you've considered
- Polyfilling Node buffer and convert the blob to that.
- Using URL.createObjectURL as pointed above.
Additional context