Last active
February 25, 2019 03:47
-
-
Save simbo/0a45c556a479032d9cd64eae2e61c3a6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { mkdirp } = require('mkdirp'); | |
const { readFile, writeFile } = require('fs'); | |
const { dirname, join } = require('path'); | |
const rimraf = require('rimraf'); | |
const { green, red, yellow } = require('chalk'); | |
const imagemin = require('imagemin'); | |
const imageminJpegRecompress = require('imagemin-jpeg-recompress'); | |
const jimp = require('jimp'); | |
const denodeify = require('denodeify'); | |
const globby = require('globby'); | |
const Queue = require('p-queue'); | |
const minimist = require('minimist'); | |
const ora = require('ora'); | |
const rootPath = dirname(__dirname); | |
const params = minimist(process.argv.slice(2)); | |
const scaleSize = parseInt(params.size, 10); | |
const quality = ['low', 'medium', 'high', 'veryhigh'] | |
.includes(params.quality) ? params.quality : 'medium'; | |
const imgInputPath = join(rootPath, 'src/raw-images'); | |
const imgOutputPath = join(rootPath, 'src/assets/images'); | |
async function optimizeImages() { | |
const spinner = ora({ | |
spinner: 'dots12', | |
color: 'cyan', | |
text: 'Processing images...' | |
}).start(); | |
await denodeify(rimraf)(imgOutputPath); | |
await denodeify(mkdirp)(imgOutputPath); | |
const imgFilenames = await globby('*.jpg', { cwd: imgInputPath }); | |
const queue = new Queue({ concurrency: 1 }); | |
const succeeded = []; | |
const failed = []; | |
imgFilenames.forEach(imgFilename => { | |
queue.add(async () => { | |
const image = { | |
name: imgFilename, | |
inputPath: join(imgInputPath, imgFilename), | |
inputSize: null, | |
outputPath: join(imgOutputPath, imgFilename), | |
outputSize: null, | |
error: null, | |
} | |
try { | |
let buffer = await denodeify(readFile)(image.inputPath); | |
image.inputSize = buffer.byteLength; | |
const img = await jimp.create(buffer); | |
img.scaleToFit(scaleSize, scaleSize, jimp.RESIZE_BICUBIC); | |
buffer = await img.getBufferAsync(jimp.MIME_JPEG); | |
buffer = await imagemin.buffer(buffer, { | |
plugins: [ | |
imageminJpegRecompress({ quality }) | |
] | |
}); | |
image.outputSize = buffer.byteLength; | |
await denodeify(writeFile)(image.outputPath, buffer); | |
succeeded.push(image); | |
} catch (err) { | |
image.error = err; | |
failed.push(image); | |
} | |
}); | |
}); | |
await queue.onEmpty(); | |
const messages = []; | |
if (succeeded.length) { | |
messages.push( | |
green(`${succeeded.length} images successfully processed.`), | |
...succeeded.map(image => ` • ${image.name} ${yellow(`${ | |
(100 - Math.round(image.outputSize / image.inputSize * 10000) / 100) * -1 | |
}%`)}`) | |
); | |
} | |
if (failed.length) { | |
messages.push( | |
red(`${failed.length} images failed processing:`), | |
...failed.map(file => red(` • ${file.name}: ${file.error.message || file.error}`)) | |
); | |
} | |
spinner.stop(); | |
console.log(messages.join('\n')); | |
} | |
optimizeImages() | |
.catch(error => console.error(error)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment