Jimp: multiple images resize

Created on 16 Mar 2018  路  6Comments  路  Source: oliver-moran/jimp

is it possible to pass a folder directory path and resize all images that are in that folder?

question

Most helpful comment

Yes it is!

const Jimp = require('jimp');
const glob = require('glob');  // yarn add glob

/**
 * Resizes images in the directory. Only operates on .png, .jpg, and .bmp.
 * @param {string} dirPath - Path to directory. Can be relative or absolute.
 * @param {Object} options
 * @param {int|Jimp.AUTO} [options.width=Jimp.AUTO]
 * @param {int|Jimp.AUTO} [options.height=Jimp.AUTO]
 * @param {boolean} [options.recursive=false] - Whether or not to also resize recursively.
 * @return {Promise}
 */
function resizeDirectoryImages(dirPath, { width = Jimp.AUTO, height = Jimp.AUTO, recursive = false }) {
  return new Promise((resolve, reject) => {
    glob((recursive ? "**/" : "") + "*.@(png|jpg|bmp)", { nocase: true, nodir: true, realpath: true, cwd: dirPath}, (err, files) => {
      if(err) {
        reject(err);
      } else {
        resolve(files);
      }
    });
  }).then(files => {
    return Promise.all(files.map(path => {
      return new Promise((resolve, reject) => {
        return Jimp.read(path).then(image => {
          image
            .resize(width, height)  // You may want to change this.
            .write(path, (err) => {
              if(err) {
                reject(err);
              } else {
                resolve(path);
              }
            });
        })
      }).then(console.log)
    }));
  });
}

resizeDirectoryImages('./example', { width: 500 })  // Resize all png, jpg, and bmp images in the example directory to be at max 500 wide
  .then(() => {
    console.log('Done!');
  });

Depending on what you want, you may need to swap out the .resize(width, height) line with a similar Jimp function like scaleToFit.

All 6 comments

Yes it is!

const Jimp = require('jimp');
const glob = require('glob');  // yarn add glob

/**
 * Resizes images in the directory. Only operates on .png, .jpg, and .bmp.
 * @param {string} dirPath - Path to directory. Can be relative or absolute.
 * @param {Object} options
 * @param {int|Jimp.AUTO} [options.width=Jimp.AUTO]
 * @param {int|Jimp.AUTO} [options.height=Jimp.AUTO]
 * @param {boolean} [options.recursive=false] - Whether or not to also resize recursively.
 * @return {Promise}
 */
function resizeDirectoryImages(dirPath, { width = Jimp.AUTO, height = Jimp.AUTO, recursive = false }) {
  return new Promise((resolve, reject) => {
    glob((recursive ? "**/" : "") + "*.@(png|jpg|bmp)", { nocase: true, nodir: true, realpath: true, cwd: dirPath}, (err, files) => {
      if(err) {
        reject(err);
      } else {
        resolve(files);
      }
    });
  }).then(files => {
    return Promise.all(files.map(path => {
      return new Promise((resolve, reject) => {
        return Jimp.read(path).then(image => {
          image
            .resize(width, height)  // You may want to change this.
            .write(path, (err) => {
              if(err) {
                reject(err);
              } else {
                resolve(path);
              }
            });
        })
      }).then(console.log)
    }));
  });
}

resizeDirectoryImages('./example', { width: 500 })  // Resize all png, jpg, and bmp images in the example directory to be at max 500 wide
  .then(() => {
    console.log('Done!');
  });

Depending on what you want, you may need to swap out the .resize(width, height) line with a similar Jimp function like scaleToFit.

@czycha that worked for me thanks ;). Question how can I process only new images just added I am using multer for uploading the images.

@czycha that worked great! thanks a lot bro, really helped!
i'll try to implement the above by adding an output directory in order not to replace exisiting images

@reachdevelopers It really depends on how you're accessing the image.

If the files are saved to disk and you are just checking occasionally, you can use fs.stat to get the last modified time and compare that to the last time you checked. Looking at multer's README, it does seem to store the files and provides for you a path.

const myMulterFiles = [ /** files uploaded through multer */ ];
let lastChecked = -1;  // Last time checked for new files in ms
function getNewFiles(myMulterFiles) {
  const newFiles = myMulterFiles.filter(file => {
    const stats = fs.statSync(file.path);
    return stats.mtimeMs > lastChecked;
  });
  lastChecked = (new Date).getTime();
  return newFiles;
}
process(getNewFiles(myMulterFiles));

If you're hoping to continually process images as they get added to a directory, I suggest you use a module like watch. Watch checks at an interval whether files have been created, removed, or modified within a directory. These actions will cause events through which you can choose to process the image. You could just set the watched directory to wherever multer saves the files.

Just note that you might accidentally create an infinite loop if you process a new image and then save it to the same directory. Either include a way to ignore files (a conventional naming pattern for processed images that you can check against) or save outside that directory.

const watch = require('watch');

watch.createMonitor('./input', monitor => {
  const process = (path, stat) => {
    /** Do something with file. For example, resize the image. 
     * Just be careful with saving to or modifying files within this directory.
     * You could accidentally create an infinite loop.
     */
  };
  monitor.on('changed', process);  // Do something when a file is modified
  monitor.on('created', process);  // Do something when a file is created
});

@czycha great solutions! I really appreciate your help on all these issues. closing as the question has been answered.

@czycha
I am trying to use your solution, but isnt working, maybe because my directory has a lot of directories?
./example/directories/images

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Inbarasan16 picture Inbarasan16  路  3Comments

Favna picture Favna  路  4Comments

haydenbleasel picture haydenbleasel  路  6Comments

master-of-null picture master-of-null  路  3Comments

maqboolkhan picture maqboolkhan  路  5Comments