1

I want to generate a pdf with images and text, for this I'm using the jsPdf package which includes this method to add images.

addImage(imageData, format, x, y, width, height, alias, compression, rotation)

The imageData argument accepts base64 format data and this part is which I'm struggling with.

My images are not local but hosted in cloudinary and I would prefer not to download them, searching on the web I've found that if I don't want to download the image I will need:

  1. Fetch the image data, for this I'm using node-fetch package(fetch in the code).
  2. Convert the image data into a Buffer.
  3. Finally encode that buffer into a base64.

This is my attempt so far:

const fetchImage = async () => {
  const imageUrl = <url-of-my-image>;

  const response = await fetch(imageUrl, {
    compress: false
  });
  const dataUrlPrefix = `data:${response.headers.get('content-type')};base64,`;

  const body = await response.text();
  const buffer = Buffer.from(body)
  const imageBase64  = buffer.toString('base64');

  const imageDataUrl = dataUrlPrefix+imageBase64;

  doc.text("Hello world!", 10, 10);
  doc.addImage(imageDataUrl, 'webp', 15, 40, 120, 120)
  doc.save("a4.pdf");  
}

The code runs without errors but the image is not being inserted into the pdf, it just display the "Hello World!" text but nothing else.

My guess is that I'm doing something wrong in the converting/encoding process (before I add it to jsPdf) because if I convert my image with an online converter like this one the base64 string that results is successfully decoded into an actual image when using a online base64 decoder like this one, whereas when I run the base64 output from my nodejs code i.e. the output for the imageBase64 or imageDataUrl variables in the same base64 decoder it results in not image being decoded.

Rob
  • 14,746
  • 28
  • 47
  • 65
GhostOrder
  • 586
  • 7
  • 21
  • @KJ yeah it is `image/webp` is just that I'm using the `response.headers.get('content-type')` method from the node-fetch that gives me the content type dynamically, I already check it and it is returning `image/webp`. – GhostOrder May 27 '22 at 00:34
  • @KJ the resulting string from `imageDataUrl` start with `data:image/webp;base64,` then there are a lot of random characters and then it ends with two equal signs. – GhostOrder May 27 '22 at 15:25
  • One thing I noticed is that the random characters generated with my nodejs code is different from the one generated by the online encoder, they both are similar in the starting characters and the final ones but for the most part they are different, and another thing is that the characters generated by my nodejs code have the strings `ve++/`, `ve+/` and `+/` being repeated a lot of times whereas the one generated by the online encoder doesn't have any of those. – GhostOrder May 27 '22 at 15:37
  • I just changed the dynamically generated content type for a hard coded one so now `const dataUrlPrefix = data:image/webp;base64,` and the result is the same as my last comment – GhostOrder May 27 '22 at 15:48
  • 1
    @KJ you're right, the text() method was encoding the response as utf8 and therefore making the resulting string unusable, I change to arrayBuffer() and it finally worked, thanks! – GhostOrder May 27 '22 at 16:55

0 Answers0