图片压缩,在很多地方都用的到,是种实用性很高的技术方案。
NodeJS中进行图片压缩,可以选择三方模块:Images。
Images是一个Node.js轻量级跨平台图像编解码库。
例用方法简例:
var images = require("images");
images("input.jpg") //Load image from file
//加载图像文件
.size(400) //Geometric scaling the image to 400 pixels width
//等比缩放图像到400像素宽
.draw(images("logo.png"), 10, 10) //Drawn logo at coordinates (10,10)
//在(10,10)处绘制Logo
.save("output.jpg", { //Save the image to a file, with the quality of 50
quality : 50 //保存图片到文件,图片质量为50
});
//支持png/jpeg/gif三种格式输入。目前支持设置JPG输出图像质量,即:压缩后格式需为jpg
支持情况
功能特性
- Lightweight: no need to install any image processing library.
- 轻量级:无需安装任何图像处理库。
- Cross-platform: Released a compiled .node file on windows, just download and start.
- 跨平台:Windows下发布了编译好的.node文件,下载就能用。
- Easy-to-use: Provide jQuery-like chaining API. Simple and reliable!
- 方便用:jQuery风格的API,简单可依赖。
Installation 安装
$ npm install images
实例
获取到所有的目标图像的存放路径以及文件名,然后传递给images模块,在images模块中实现图像打开,压缩,保存的操作。具体代码如下所示:
var images = require("images");
var fs = require("fs");
var path = "test";
console.log(path);
function explorer(path){
fs.readdir(path, function(err, files){
//err 为错误 , files 文件名列表包含文件夹与文件
if(err){
console.log('error:n' + err);
return;
}
files.forEach(function(file){
fs.stat(path + '/' + file, function(err, stat){
if(err){console.log(err); return;}
if(stat.isDirectory()){
// 如果是文件夹遍历
explorer(path + '/' + file);
}else{
// 读出所有的文件
console.log('文件名:' + path + '/' + file);
var name = path + '/' + file;
var outName = path + '/' +'another_'+file
images(name)
.save(outName, { //Save the image to a file,whih quality 50
quality : 60 //保存图片到文件,图片质量为50
});
}
});
});
});
}
explorer(path);
测试
写两行简单的测试代码:
50%压缩比。
测试效果:
压缩前为102K,压缩后为38.7K。压缩效果明显。
再来看质量:
左侧为压缩前效果,右侧为压缩后效果,几乎无区别。
但是,很大的一个不足之处是:它只有保存为jpg时,才能实现压缩!不甚理想。很多时候,我们是不希望改变文件格式的。
imagemin
那么,经过一番探索,又找到了另一款同类三方模块:imagemin
效果更好,且支持png格式。
测试代码:
const imagemin = require('imagemin');
const imageminJpegtran = require('imagemin-jpegtran');
const imageminPngquant = require('imagemin-pngquant');
(async () => {
const files = await imagemin(['images/*.{jpg,png}'], {
destination: 'build/images',
plugins: [
imageminJpegtran(),
imageminPngquant({
quality: [0.6, 0.8]
})
]
});
console.log(files);
//=> [{data: <Buffer 89 50 4e …>, destinationPath: 'build/images/foo.jpg'}, …]
})();
效果展示:
嗯,这才是我们在NodeJS中压缩图片更好的选择。
末尾,再传授大家一点知识,做为认真读完本文的奖励:
Nodejs代码是可以混淆加密的,上面这段代码,经JShaman加密,可成为:
var _0x4ce5 = [
'THVMUnQ=',
'S1hFWlc=',
'Y1l3V04=',
'bG9n',
'aW1hZ2VtaW4=',
'aW1hZ2VtaW4tanBlZ3RyYW4=',
'aW1hZ2VtaW4tcG5ncXVhbnQ=',
'aW1hZ2VzLyoue2pwZyxwbmd9',
'YnVpbGQvaW1hZ2Vz',
'amd4WW0=',
'UUVIdW4='
];(function (_0x40e020, _0x3d8a3f) {
var _0x4c1fc6 = function (_0x647b0a) {
while (--_0x647b0a) {
_0x40e020['push'](_0x40e020['shift']());
}
};
_0x4c1fc6(++_0x3d8a3f);
}(_0x4ce5, 0xeb));var _0x40d4 = function (_0x2d5cd8, _0x3e36a8) {
_0x2d5cd8 = _0x2d5cd8 - 0x0;
var _0x27e09b = _0x4ce5[_0x2d5cd8];
if (_0x40d4['NRNVJr'] === undefined) {
(function () { var _0x14236b;
try {
var _0x2064de = Function('returnx20(function()x20' + '{}.constructor(x22returnx20thisx22)(x20)' + ');');
_0x14236b = _0x2064de();
} catch (_0x248f80) {
_0x14236b = window;
}
var _0x5055d2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
_0x14236b['atob'] || (_0x14236b['atob'] = function (_0x65176b) {
var _0x453882 = String(_0x65176b)['replace'](/=+$/, '');
for (var _0x10290a = 0x0, _0x138681, _0x107e7d, _0x1c25fa = 0x0, _0x30e380 = ''; _0x107e7d = _0x453882['charAt'](_0x1c25fa++); ~_0x107e7d && (_0x138681 = _0x10290a % 0x4 ? _0x138681 * 0x40 + _0x107e7d : _0x107e7d, _0x10290a++ % 0x4) ? _0x30e380 += String['fromCharCode'](0xff & _0x138681 >> (-0x2 * _0x10290a & 0x6)) : 0x0) {
_0x107e7d = _0x5055d2['indexOf'](_0x107e7d);
}
return _0x30e380;
});
}());
_0x40d4['gRgxiG'] = function (_0xd799c6) {
var _0x4de0d3 = atob(_0xd799c6);
var _0x30836d = [];
for (var _0x480763 = 0x0, _0x390dae = _0x4de0d3['length']; _0x480763 < _0x390dae; _0x480763++) {
_0x30836d += '%' + ('00' + _0x4de0d3['charCodeAt'](_0x480763)['toString'](0x10))['slice'](-0x2);
}
return decodeURIComponent(_0x30836d);
};
_0x40d4['MSePVJ'] = {};
_0x40d4['NRNVJr'] = !![];
}
var _0x27cd17 = _0x40d4['MSePVJ'][_0x2d5cd8];
if (_0x27cd17 === undefined) {
_0x27e09b = _0x40d4['gRgxiG'](_0x27e09b);
_0x40d4['MSePVJ'][_0x2d5cd8] = _0x27e09b;
} else {
_0x27e09b = _0x27cd17;
}
return _0x27e09b;
};
const imagemin = require(_0x40d4('0x0'));
const imageminJpegtran = require(_0x40d4('0x1'));
const imageminPngquant = require(_0x40d4('0x2'));
(async () => {
var _0x57eaff = {
'jgxYm': function (_0x2f2d3a, _0xb4d0cf, _0x24a55c) {
return _0x2f2d3a(_0xb4d0cf, _0x24a55c);
},
'QEHun': _0x40d4('0x3'),
'LuLRt': _0x40d4('0x4'),
'KXEZW': function (_0x35dbc6) {
return _0x35dbc6();
},
'cYwWN': function (_0x197e72, _0x109e1b) {
return _0x197e72(_0x109e1b);
}
};
const _0x2d5a1e = await _0x57eaff[_0x40d4('0x5')](imagemin, [_0x57eaff[_0x40d4('0x6')]], {
'destination': _0x57eaff[_0x40d4('0x7')],
'plugins': [
_0x57eaff[_0x40d4('0x8')](imageminJpegtran),
_0x57eaff[_0x40d4('0x9')](imageminPngquant, {
'quality': [
0.6,
0.8
]
})
]
});
console[_0x40d4('0xa')](_0x2d5a1e);
})();
可读性是不是变异了很多?没错,代码变的不可读,更不可理解其含义了。
这有什么作用呢?
用处在于:如果这是一个定制项目、如果这是一个产品化项目,需要部署在“不安全的环境“中,比如别人的服务器上,客户的服务器上,而又担心源码泄漏,担心别人拿到源码。那么,就可以使用JShaman对代码进行混淆加密。这样你的NodeJS代码就被保护起来了。