Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

imagemin

Package Overview
Dependencies
Maintainers
2
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

imagemin - npm Package Compare versions

Comparing version 0.1.3 to 0.2.4

304

index.js

@@ -0,249 +1,123 @@

'use strict';
var pipeline = require('multipipe');
var spawn = require('win-spawn');
var through = require('through2');
/**
* 代码修改自grunt-img
* Initialize `Imagemin` with options
*
* @param {Object} opts
* @api private
*/
'use strict';
var fs = require('fs');
var path = require('path');
var child_process = require('child_process');
var spawn = child_process.spawn;
//非系统模块
var which = require('which');
var log = require('./lib/log');
var pngcrush = require('node-pngcrush');
var emptyFn = function() {};
function Imagemin(opts) {
opts = opts || {};
this.opts = opts;
this.optimizer = this._getOptimizer(opts.ext);
this.optimizationLevel = opts.optimizationLevel || 7;
}
var win32 = process.platform === 'win32';
var png = ['.png', '.bmp', '.gif', '.pnm', '.tiff'],
jpegs = ['.jpg', 'jpeg'];
var imagemin = module.exports = function(dir, destDir, cb) {
destDir = destDir || '';
if (typeof destDir === 'function') {
cb = destDir;
}
if (typeof cb !== 'function') {
cb = emptyFn;
}
/**
* Optimize GIF, JPEG, and PNG images
*
* @api public
*/
Imagemin.prototype.optimize = function () {
var cp = this.optimizer();
var stream = through();
var files = [];
if (Array.isArray(dir)) {
dir.forEach(function(v) {
imagemin(v, destDir, cb);
});
return;
}
return pipeline(stream, cp.stdin, cp.stdout);
};
if (fs.statSync(dir).isDirectory()) {
//遍历目录
recurse(dir, function(filepath, rootdir, subdir, filename) {
files.push(filepath);
});
} else {
//是文件
files.push(dir);
}
/**
* Get the optimizer for a desired file extension
*
* @param {String} ext
* @api private
*/
var pngfiles = files.filter(function(file) {
return !!~png.indexOf(path.extname(file).toLowerCase());
});
Imagemin.prototype._getOptimizer = function (ext) {
ext = ext ? ext.toLowerCase() : null;
var jpgfiles = files.filter(function(file) {
return !!~jpegs.indexOf(path.extname(file).toLowerCase());
});
var optimizers = {
'.gif': this._optimizeGif,
'.jpg': this._optimizeJpeg,
'.jpeg': this._optimizeJpeg,
'.png': this._optimizePng
};
log.writeln('Running imagemin task... ');
pngc(pngfiles, destDir, function() {
jpegtran(jpgfiles, {}, destDir, function(err) {
if (err) {
log.error(err);
}
cb();
});
});
return optimizers[ext];
};
function pngc(files, output, cb) {
cb = cb || emptyFn;
if (!files.length) {
return cb();
}
/**
* Optimize a GIF image
*
* @api private
*/
var isOutDir = false;
if (output) {
var ext = path.extname(output).toLowerCase();
if ( !! ~png.indexOf(ext)) {
//文件
Imagemin.prototype._optimizeGif = function () {
var args = ['-w'];
var gifsicle = require('gifsicle').path;
} else {
if (!/\/$/.test(output)) {
output += path.sep;
}
if (!fs.existsSync(output)) {
output = '';
}
//目录
isOutDir = true;
}
if (this.opts.interlaced) {
args.push('--interlace');
}
var file;
while (file = files.shift()) {
var data = fs.readFileSync(file);
var buffer = pngcrush.compress(data);
log.writeln('*Processing: '.cyan + path.normalize(file));
var outfile = file;
var min = file,
max = file;
if (output !== '') {
outfile = isOutDir ? output + path.basename(file) : output;
min = outfile;
} else {
min = {
size: buffer.length
};
max = {
size: data.length
};
}
log.writeln('Output file: '.cyan + path.normalize(outfile));
fs.writeFileSync(outfile, buffer, {
flags: 'wb'
});
min_max_stat(min, max);
}
cb();
}
function jpegtran(files, opts, output, cb) {
opts = opts || {};
cb = cb || function() {};
opts.args = opts.args ? opts.args : ['-copy', 'none', '-optimize', '-outfile', 'jpgtmp.jpg'];
return spawn(gifsicle, args);
};
which_bin('jpegtran', function(err, cmdpath) {
if (err) return not_installed('jpegtran', cb);
(function run(file) {
if (!file) return cb();
/**
* Optimize a JPEG image
*
* @api private
*/
log.writeln('*Processing: '.cyan + path.normalize(file));
Imagemin.prototype._optimizeJpeg = function () {
var args = ['-copy', 'none', '-optimize'];
var jpegtran = require('jpegtran-bin').path;
var jpegtran = spawn(cmdpath, opts.args.concat(file), function() {});
if (this.opts.progressive) {
args.push('-progressive');
}
var outputPath;
if (output) {
var ext = path.extname(output).toLowerCase();
if ( !! ~jpegs.indexOf(ext)) {
//文件
outputPath = output;
} else {
if (!/\/$/.test(output)) {
output += path.sep;
}
outputPath = output + path.basename(file);
}
try {
fs.readFileSync(outputPath);
} catch (err) {
fs.writeFileSync(outputPath);
}
log.writeln('Output file: '.cyan + path.normalize(outputPath));
} else {
outputPath = file;
}
jpegtran.stdout.pipe(process.stdout);
jpegtran.stderr.pipe(process.stderr);
jpegtran.on('exit', function(code) {
if (code) return log.warn('jpgtran exited unexpectedly with exit code ' + code);
// output some size info about the file
min_max_stat('jpgtmp.jpg', file);
// copy the temporary optimized jpg to original file
fs.createReadStream('jpgtmp.jpg')
.pipe(fs.createWriteStream(outputPath)).on('close', function() {
//删除
fs.unlinkSync('jpgtmp.jpg');
run(files.shift());
});
});
}(files.shift()));
});
return spawn(jpegtran, args);
};
/**
* Optimize a PNG image
*
* @api private
*/
// Output some size info about a file, from a stat object.
Imagemin.prototype._optimizePng = function () {
var args = ['-strip', 'all', '-quiet'];
var optipng = require('optipng-bin').path;
var pngquant;
function min_max_stat(min, max) {
min = typeof min === 'string' ? fs.statSync(min) : min;
max = typeof max === 'string' ? fs.statSync(max) : max;
log.writeln('Uncompressed size: ' + String(max.size).green + ' bytes.');
log.writeln('Compressed size: ' + String(min.size).green + ' bytes (' + String(max.size - min.size).green + ' bytes = ' + (String((max.size - min.size) / max.size * 100).slice(0, 5) + '%').green + ' decrease).');
if (typeof this.optimizationLevel === 'number') {
args.push('-o', this.optimizationLevel);
}
};
if (this.opts.pngquant) {
pngquant = require('pngquant-bin').path;
return spawn(optipng, args).stdout.pipe(spawn(pngquant, ['-']));
}
function not_installed(cmd, cb) {
log.log('[Running ' + cmd + '...](error)');
log.writeln([
'In order for this task to work properly, :cmd must be',
'installed and in the system PATH (if you can run ":cmd" at',
'the command line, this task should work)'
].join(' ').replace(/:cmd/g, cmd));
log.writeln('Skiping ' + cmd + ' task');
if (cb) cb();
return spawn(optipng, args);
};
var unixifyPath = function(filepath) {
if (win32) {
return filepath.replace(/\\/g, '/');
} else {
return filepath;
}
};
/**
* 遍历
* @param {[type]} rootdir [description]
* @param {Function} callback [description]
* @param {[type]} subdir [description]
* @param {[type]} judgeFunction [description]
* @return {[type]} [description]
* Module exports
*/
function recurse(rootdir, callback, subdir, judgeFunction) {
var abspath = subdir ? path.join(rootdir, subdir) : rootdir;
subdir = subdir || '';
judgeFunction = typeof judgeFunction === 'function' ? judgeFunction : function() {
return true;
};
fs.readdirSync(abspath).forEach(function(filename) {
var filepath = path.join(abspath, filename);
if (fs.statSync(filepath).isDirectory() && judgeFunction(filename)) {
recurse(rootdir, callback, unixifyPath(path.join(subdir, filename)), judgeFunction);
} else {
judgeFunction(filename) && callback(unixifyPath(filepath), rootdir, subdir, filename, judgeFunction);
}
});
module.exports = function (opts) {
var imagemin = new Imagemin(opts);
}
// **which** helper, wrapper to isaacs/which package plus some fallback logic
// specifically for the win32 binaries in vendor/ (optipng.exe, jpegtran.exe)
function which_bin(cmd, cb) {
if (!win32 || !/optipng|jpegtran/.test(cmd)) return which(cmd, cb);
var jpegtran = './vendor/jpegtran-turbo/win32/jpegtran.exe';
if (process.arch === 'x64') {
jpegtran = './vendor/jpegtran-turbo/win64/jpegtran.exe';
if (!imagemin.optimizer) {
return through();
}
var cmdpath = cmd === 'optipng' ? './vendor/optipng-0.7.4-win32/optipng.exe' :
jpegtran;
cb(null, path.join(__dirname, cmdpath));
};
return imagemin.optimize();
};
{
"name": "imagemin",
"version": "0.1.3",
"description": "A tool to optimize png and jpg images with optipng & jpegtran",
"keywords": [
"png",
"jpg",
"image optimizer",
"compress image",
"image",
"web performance"
],
"homepage": "https://github.com/ksky521/imagemin",
"bugs": "https://github.com/ksky521/imagemin/issues",
"author": {
"name": "Theowang",
"email": "ksky521@gmail.com",
"url": "http://js.in"
},
"main": "index.js",
"bin": {
"imagemin": "bin/imagemin"
},
"repository": {
"type": "git",
"url": "git://github.com/ksky521/imagemin.git"
},
"dependencies": {
"colors": "~0.6.2",
"which": "~1.0.5",
"optimist": "~0.6.0",
"node-pngcrush": "~0.0.9",
"read": "~1.0.4"
},
"scripts": {
"install": "node ./bin/install",
"uninstall": "node ./bin/uninstall"
},
"engines": {
"node": ">=0.6.0"
},
"licenses": {
"type": "MIT"
}
}
"name": "imagemin",
"version": "0.2.4",
"description": "Minify GIF, JPEG and PNG images",
"license": "MIT",
"repository": "kevva/image-min",
"author": {
"name": "Kevin Mårtensson",
"email": "kevinmartensson@gmail.com",
"url": "https://github.com/kevva"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "mocha --reporter list --timeout 500000"
},
"files": [
"index.js"
],
"keywords": [
"extract",
"tar",
"tar.gz",
"zip"
],
"dependencies": {
"multipipe": "0.0.2",
"through2": "^0.4.0",
"win-spawn": "^2.0.0"
},
"devDependencies": {
"mocha": "^1.17.1",
"rimraf": "^2.2.6"
},
"optionalDependencies": {
"gifsicle": "^0.1.0",
"jpegtran-bin": "^0.2.0",
"optipng-bin": "^0.3.2",
"pngquant-bin": "^0.1.6"
}
}

@@ -1,54 +0,70 @@

imagemin
=============
# image-min [![Build Status](https://secure.travis-ci.org/kevva/image-min.png?branch=master)](http://travis-ci.org/kevva/image-min)
A tool which fork from [grunt-img][grunt-img] to optimize PNG and JPG images with [pngcrush][node-pngcrush] & [jpegtran][jpegtran] ([jpegtran-turbo][jpegtran-turbo] on win32).
> Minify GIF, JPEG and PNG images seamlessly with Node.js.
## Getting Started
## Install
First, be sure that you have [jpegtran][jpegtran] installed in your system.
### for Mac users
You can install with [homebrew][homebrew]
```shell
brew install jpeg
```bash
npm install --save image-min
```
### for Linux users
Debian, Ubuntu and Mint
```shell
apt-get install libjpeg libjpeg-progs
```
Both libraries are easy to find for RPM distributions too.
## Usage
### for Windows users
Don't worry because both libraries are included.
```js
var fs = require('fs');
var imagemin = require('image-min');
var path = require('path');
### Install
```shell
npm install imagemin
var src = fs.createReadStream('img.gif');
var ext = path.extname(src.path);
src
.pipe(imagemin({ ext: ext }))
.pipe(fs.createWriteStream('img-minified' + ext));
```
## How to use
## API
### for shell
```shell
imagemin file/path
imagemin file/path -o new/file/path
```
### for nodejs
```js
var imagemin = require('imagemin');
imagemin(filePath, destDir, callback);
```
### imagemin(opts)
Credits
---------------
* Grunt-image [Helder Santana](http://heldr.com)
* node-pngcrush [node-pngcrush](https://github.com/xiangshouding/node-pngcrush)
Optimize a `GIF`, `JPEG`, or `PNG` image by providing a an `ext`. Use the
options below (optionally) to configure how your images are optimized.
[node-build-script]: http://github.com/h5bp/node-build-script
[grunt-img]: https://github.com/heldr/grunt-img
[jpegtran]: http://jpegclub.org/jpegtran/
[jpegtran-turbo]: http://libjpeg-turbo.virtualgl.org/
[node-pngcrush]: https://github.com/xiangshouding/node-pngcrush
[homebrew]: http://mxcl.github.com/homebrew/
## Options
### ext
Type `String`
Default: `undefined`
File extension used by imagemin to determine which optimizer to use.
### interlaced (GIF only)
Type: `Boolean`
Default: `false`
Interlace gif for progressive rendering.
### pngquant (PNG only)
Type: `Boolean`
Default: `false`
Whether to enable [pngquant](https://github.com/pornel/pngquant) lossy compression.
### progressive (JPEG only)
Type: `Boolean`
Default: `false`
Lossless conversion to progressive.
## Used by
* [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin)
* [grunt-contrib-imagemin](https://github.com/gruntjs/grunt-contrib-imagemin)
## License
[MIT License](http://en.wikipedia.org/wiki/MIT_License) © [Kevin Mårtensson](http://kevinmartensson.com)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc