Skip to content

Instantly share code, notes, and snippets.

@joebasirico
Last active December 7, 2019 00:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joebasirico/a479e33a4dfc39d198d712f9b5213ac2 to your computer and use it in GitHub Desktop.
Save joebasirico/a479e33a4dfc39d198d712f9b5213ac2 to your computer and use it in GitHub Desktop.
A command line image optimizer written in node.
#!/usr/bin/env node
const sharp = require('sharp');
const fs = require('fs');
const program = require('commander');
const chalk = require('chalk');
function increaseVerbosity(v, total) {
return total + 1;
}
program
.version('0.1.1', '-V, --version')
.option('-w, --width <width>', 'The maximum width of each image. Aspect ' +
'ratio will remain. Images smaller than max will not be scaled.',
parseInt)
.option('-v, --verbose', 'Output additional stats, three levels',
increaseVerbosity, 0)
.option('-q, --quality <quality>', 'The quality factor for jpg images (no ' +
'effect for png). Values: 0-100', parseInt)
.option('-c, --copy_others', 'Copy non jpg or png files to destination ' +
'directory. Good if you are also includeing PDF or other filetypes in ' +
'the directory.')
.option('-o, --overwrite', 'Overwrite all destination files')
.arguments('<source> <destination>')
.action(function(source, destination) {
var width, quality, copy_others;
if (!fs.existsSync(source)) {
console.error(chalk.bold.red('Source directory does not exist, ' +
'please verify.'));
process.exit(1);
}
if (!fs.existsSync(destination)) {
console.log('Destination directory does not exist, creating it.')
fs.mkdirSync(destination);
}
program.width ? width = program.width : width = 2560;
program.quality ? quality = program.quality : quality = 80;
program.copy_others ? copy_others = program.copy_others : copy_others = false;
if (quality > 100 || quality < 0) {
console.error(chalk.bold.red('quality must be greater than 0 and ' +
'less than 100'));
process.exit(1);
}
fs.readdir(source, function(err, files) {
var jpg = 0;
var png = 0;
var other = 0;
var skipped = 0;
for (var i in files) {
if (!fs.existsSync(destination + files[i]) || program.overwrite) {
file = source + files[i];
if (file.endsWith('png')) {
png++;
if (program.verbose > 2)
console.log('resize ' + file);
sharp(file)
.resize({
width: width,
withoutEnlargement: true})
.png()
.toFile(destination + files[i]);
} else if (file.endsWith('jpg')) {
jpg++;
if (program.verbose > 2)
console.log('resize ' + file);
sharp(file)
.resize({
width: width,
withoutEnlargement: true})
.jpeg({
quality: quality,
optimizeScans: true
})
.toFile(destination + files[i]);
} else if (copy_others) {
other++;
if (program.verbose > 2)
console.log('move ' + file);
fs.createReadStream(file).pipe(fs.createWriteStream(
destination + files[i]));
}
} else {
if (program.verbose > 2) {
file = source + files[i];
console.log('skipped ' + file);
}
skipped++;
}
}
if (err) {
console.error(chalk.bold.red(err));
}
if (program.verbose > 0) {
total = png + jpg + other;
console.log(chalk.bold('================================='));
console.log(chalk.bold('Processed ' + total + ' files.'));
if (program.verbose > 1) {
console.log(' skipped ' + skipped + ' files.')
console.log(' ' + png + ' png files.');
console.log(' ' + jpg + ' jpg files.');
console.log(' ' + other + ' other files.');
}
if (program.width)
console.log('scaled images to ' + width + ' pixels wide');
if (program.quality)
console.log('set quality for jpg to ' + quality + '%');
console.log('Source: ' + source);
console.log('Destination: ' + destination);
console.log(chalk.bold('================================='));
}
});
}).parse(process.argv)
@joebasirico
Copy link
Author

TODO

  • Support GIF and other formats
  • Better error handling
  • Add a progress bar?
  • Comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment