UNPKG

gulp-upng

Version:
122 lines (104 loc) 3.62 kB
const through = require('through2'); const gutil = require('gulp-util'); const UPNG = require('upng-js'); const PluginError = gutil.PluginError; // 常量 const PLUGIN_NAME = 'gulp-upng'; /** * @description Buffer 转换为 ArrayBuffer * @author cairc * @param {any} buf * @returns */ function toArrayBuffer(buf) { const ab = new ArrayBuffer(buf.length); const view = new Uint8Array(ab); for (let i = 0; i < buf.length; ++i) { view[i] = buf[i]; } return ab; } /** * @description ArrayBuffer 转换为 Buffer * @author cairc * @param {any} buf * @returns */ function toBuffer(ab) { const buf = new Buffer(ab.byteLength); const view = new Uint8Array(ab); for (let i = 0; i < buf.length; ++i) { buf[i] = view[i]; } return buf; } const OPTIONS = { // 结果中的颜色数量; 0:所有颜色(无损PNG) 'cnum': 256, 'showLog': false }; /** * @description 插件级别函数 (处理文件) * @author cairc * @param {any} options * @returns */ function gulpUPng(options) { const opts = Object.assign({}, OPTIONS, options); // 创建一个让每个文件通过的 stream 通道 const stream = through.obj(function(file, enc, callback) { if (file.isNull() || !/\.png$/.test(file.relative)) { this.push(file); // Do nothing if no contents OR not png file return callback(); } if (file.isStream()) { this.emit('error', new PluginError(PLUGIN_NAME, 'Stream is not supported!')); return callback(); } if (file.isBuffer()) { const ubuff = new Uint8Array(toArrayBuffer(file.contents)); var mgc=[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; let fileSupport =true; for(var i=0; i<8; i++) { if(mgc[i]!=ubuff[i]){ fileSupport =false; break; } } if(!fileSupport){ this.push(file); if (opts.showLog) { gutil.log('gulp-upng: ', gutil.colors.red('✘ ') + file.relative + ' (file is not support)'); } }else{ const img = UPNG.decode(ubuff); const rgba = UPNG.toRGBA8(img)[0]; const npng = { 'name': file.relative, 'width': img.width, 'height': img.height, 'odata': ubuff, 'orgba': new Uint8Array(rgba), 'ndata': null }; npng.ndata = UPNG.encode([npng.orgba.buffer], npng.width, npng.height, opts.cnum); if (npng.ndata.byteLength > npng.odata.byteLength) { npng.ndata = npng.odata; } const os = npng.odata.byteLength; const ns = npng.ndata.byteLength; if (opts.showLog) { gutil.log('gulp-upng: ', gutil.colors.green('✔ ') + file.relative + ' (saved ' + ((os - ns) / os * 100).toFixed(0) + '%)'); } // 确保文件进去下一个插件 file.contents = toBuffer(npng.ndata); this.push(file); } } callback(); }); // 返回文件 stream return stream; } // 暴露(export)插件的主函数 module.exports = gulpUPng;