Search code examples
node.jsphantomjsjpegpuppeteer

Change JPEG file DPI header in Node.js


I have a file (for example JPEG size 1588 × 2244px). It's generated by puppeteer (but phantomjs also generate 72 DPI screenshot). When I save this image into a file with .jpeg extension and I use macOS General Info I see:

enter image description here

As you can see it has 72 DPI set in metadata, but I want to use file with 300 DPI. I know, that in digital it doesn't change anything - it's property for printing, but I don't want to explain to each customer that this file could be print in 300 DPI.

When I use Gimp and Image > Print Size

enter image description here

I can change the DPI, and export a picture again. And now it has 300 DPI in General Info window.

enter image description here

I try to do it in Node.JS server, but I found few options to change this property on .PNG pictures, but anyone is working for .JPEG files.

I think that the most accurate option is to use method changeDpiDataUrl from this library: https://github.com/shutterstock/changeDPI/blob/master/src/index.js But when I put my image as base64image, after a split operation I have the array with 1 element only - I think that this is body, so I don't have format property (at 63 line).

Anybody meet this problem before?


Solution

  • You can use the library piexifjs to change the EXIF data of an image. The library only changes the meta data (called EXIF), not the image itself.

    Code Sample

    The following code uses the API to read the EXIF data of an image, change it and create a new buffer from the changed data.

    const piexif = require("piexifjs");
    
    // get the image buffer from puppeteer or from disk
    const imageBuffer = /* ... */
    
    // convert buffer to string and load it
    const imageString = imageBuffer.toString('binary');
    const exif = piexif.load(imageString);
    
    // change resolution
    exif['0th'][piexif.ImageIFD.XResolution] = [300,1];
    exif['0th'][piexif.ImageIFD.YResolution] = [300,1];
    
    // generate new EXIF data
    const newExifDump = piexif.dump(exif);
    
    // generate new image
    const newData = piexif.insert(newExifDump, imageString);
    const jpgBuffer = new Buffer(newData, "binary");
    
    // write to file or use buffer
    // ...
    

    Be aware, that I have not used the library myself, nor have I tested the code.