0

For a few days now i have been trying to extract images from a pdf, modify them, and then replace them in my pdf document. It works perfectly when working with jpeg images, but when it comes to png... I'm able to modify the image and then save it correctly, but when changing the buffer in the pdf, it turns all black. So there's my code :

try {
      (async () => {
        let imageData = imgTab.type === 'jpg' ? imgTab.data : await savePng(imgTab);
        console.log(imgTab.type);
        let typeJimp = "image/png";
        if(imgTab.type === 'jpg'){
          typeJimp = "image/jpeg";
        }

        const img = await Jimp.read(imageData).then(async function (image) {
          image.color([
            { apply: 'hue', params: [90] }]);

          *//HERE, the image saved is okay! It is modified as I want it to be* 
          image.write("testimage"+objIdx+"."+imgTab.type);

          let data = fs.readFileSync("testimage"+objIdx+"."+imgTab.type);
          let bufferData = Buffer.from(data); 
          
          *//The problem is when i do this to replace the buffer of my original image*
          pdfObject.contents = bufferData;

          fs.writeFileSync('client/public/test_modified.pdf', await pdfDoc.save());    

        }).catch(function (err) {
          //return Promise.reject(err);
          console.log(err);
        }); 
      })();        
    }

The main code to extract the images can be found here : pdf-lib extract images

I don't know if there's something special to do to make the buffer work, but if you do, feel free :) Thanks in advance !

////

Okay, so for now, i just use it that way :

const img = await Jimp.read(imageData).then(async function (image) {

          image.color([
            { apply: 'hue', params: [90] }]);
          
          let data = await image.getBufferAsync('image/jpeg')


          var res = await pdfDoc.embedJpg(data);
          res.ref = pdfRef;
          var test = await res.embed();

          fs.writeFileSync('client/public/test_modified.pdf', await pdfDoc.save());    
        })
    

My pdfRef is the ref of the initial object i was trying to modify.

  • Ummm, you can't have a PNG image in a PDF file, at least not as a rendered object (you could add it as an embedded file, which is basically just an attachment). While JPEG is supported via the DCTDecode filter, and JPEG2000, there is no support for PNG. So any PNG image will have been turned into 'something else' which may mean, as KJ implies, that it is actually two image; the image data and the alpha channel as a separate mask or soft mask. – KenS Apr 26 '22 at 12:19
  • @KenS Thanks for your reply ! I see what you mean with your two images, as the savePng function found in Hopding's project is taking care of that. At first I wanted to extract the images and then embed them at the same location as the previous image. But I didn't find any way to get the position of an object with the library, nor the size in the document of the actual object so I don't really know what to do now :/ – bloomlaterencore Apr 26 '22 at 12:25
  • Simply replacing the image stream (the dictionary and associated data) will render at the same position and size as the original did, because the scaling and position are set up in the content stream, not the image stream. It is possible to modify a PDF file by appending an updated object to the end, with a new generation number, and then writing a modified xref to point the object number for the image to your modified image. If your replacement also has an alpha channel then you would need to write that as well, with a new object number. None of this is trivial I'm afraid. – KenS Apr 26 '22 at 13:29
  • @KenS I'm going to try that in the following days ; right now i'm trying to understand how to build the dictionary to update it once i modify my image. Thanks for your reply and your time ! – bloomlaterencore Apr 26 '22 at 13:36
  • Okay, so I was able to modify it by using the embed method ! For now, i convert my pngs into jpg images but i'm going to investigate how to make it still a png when i'll have time. Thanks ! @KJ – bloomlaterencore Apr 27 '22 at 08:31

0 Answers0