Search code examples
node.jsapijpeglibjpeg

Convert Normal Image into Progressive Image using Node Js


Is there any way to write API which will convert normal image into Progressive Using Nodejs. I don't want to use Base64. I have done so much R & D on this. One library i found i.e lib turbo-jpeg But in this only they are decoding the image .I want to encode that image too. Please check this below link for reference. If anyone got any solution then please let me know.

Link is - https://github.com/LinusU/cwasm-jpeg-turbo

Please help me out to write API to convert image into progreesive.

Thank you in advance.


Solution

  • You can use with gm module to convert supported image formats to progressive JPEG.

    Here's a simple example (tested on macOS with GraphicsMagick v1.3.31 and Node.js v10.15.3):

    const fs = require('fs');
    const path = require('path');
    const https = require('https');
    
    const gm = require('gm'); // https://www.npmjs.com/package/gm
    
    const gmIdentify = gmInstance =>
      new Promise((resolve, reject) => {
        gmInstance.identify((err, data) => {
          if (err) {
            reject(err);
            return;
          }
          resolve(data);
        });
      });
    
    const gmStream = (gmInstance, writeStream, format = 'jpg') =>
      new Promise((resolve, reject) => {
        gmInstance
          .stream(format)
          .pipe(writeStream)
          .once('finish', resolve)
          .once('error', reject);
      });
    
    // This function downloads the file from the specified `url` and writes it to
    // the passed `writeStream`.
    const fetchFile = (url, writeStream) =>
      new Promise((resolve, reject) => {
        https.get(url, res => {
          if (res.statusCode !== 200) {
            reject(new Error('Something went wrong!'));
            return;
          }
    
          res
            .pipe(writeStream)
            .once('finish', () => {
              resolve();
            })
            .once('error', err => {
              reject(err);
            });
        });
      });
    
    const main = async () => {
      // Download a sample non-progressive JPEG image from the internet
      const originalJpegUrl =
        'https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg';
      const originalPath = path.join(__dirname, './original.jpeg');
      await fetchFile(originalJpegUrl, fs.createWriteStream(originalPath));
      originalJpegData = await gmIdentify(gm(fs.createReadStream(originalPath)));
      console.log(
        `Interlace for the original jpeg file is set to ${
          originalJpegData['Interlace']
        }`,
      );
    
      // Convert the downloaded file to Progressive-JPEG
      const progressiveJpegPath = path.join(__dirname, 'progressive.jpg');
      await gmStream(
        gm(fs.createReadStream(originalPath))
          .interlace('line' /* or 'plane' */) // https://www.imagemagick.org/MagickStudio/Interlace.html
          .quality(originalJpegData['JPEG-Quality']), // save with the same quality as the original file
        fs.createWriteStream(progressiveJpegPath),
      );
      const progressiveJpegData = await gmIdentify(
        gm(fs.createReadStream(progressiveJpegPath)),
      );
      console.log(
        `Interlace for the converted jpeg file is set to ${
          progressiveJpegData['Interlace']
        }`,
      );
    };
    
    main();
    

    It downloads this non-progressive JPEG image and converts it to a progressive JPEG image and saves it as progressive.jpg in the same directory as the script.