UNPKG

9.24 kBJavaScriptView Raw
1'use strict';
2/**
3 * 图片压缩处理
4 * - 用于压缩png、svg、jpeg等图片
5 *
6 * @class Compile
7 * {
8 * src:'', <string> 源文件路径
9 * dist:'', <string> 输出路径
10 * }
11 */
12class Compile{
13 constructor(option){
14 const _ts = this;
15
16 option = option || {};
17
18 let m = _ts.m = {
19 fs:require('fs-extra'),
20 path:require('path'),
21 pathInfo:require('../lib/getPathInfo'),
22 copy:require('../lib/copy'),
23 Svgo:require('svgo'),
24 imagemin:require('imagemin'),
25 imagemin_pngquant:require('imagemin-pngquant'),
26 imagemin_jpegrecompress:require('imagemin-jpeg-recompress'),
27 imagemin_gifsicle:require('imagemin-gifsicle')
28 },
29 config = _ts.config = {};
30
31 //配置写入到_ts.config
32 for(let i in option){
33 config[i] = option[i];
34 };
35 let src = config.src,
36 dist = config.dist;
37
38 return _ts.taskList();
39 }
40
41 taskList(){
42 const _ts = this,
43 m = _ts.m,
44 config = _ts.config;
45
46 return new Promise((resolve,reject)=>{
47
48 //读取文件内容
49 let distDir = m.path.dirname(config.dist),
50 extension = m.pathInfo(config.src).extension,
51 isImg = (()=>{
52 let type = ['png','jpg','jpeg','svg','gif'];
53 return type.some(item => {
54 return extension === '.'+item;
55 });
56 })();
57
58 if(isImg){
59 //svg格式处理
60 if(extension === '.svg'){
61 //读取svg内容
62 let svgContent = m.fs.readFileSync(config.src);
63
64 //压缩svg
65 new m.Svgo({}).optimize(svgContent,result => {
66 svgContent = result.data;
67 });
68
69 //写入新的压缩文件
70 m.fs.ensureDir(distDir,err => {
71 if(err){
72 reject({
73 status:'error',
74 msg:`${distDir} 创建失败`,
75 infor:err
76 });
77 };
78 try{
79 m.fs.writeFileSync(config.dist,svgContent);
80 resolve({
81 status:'success',
82 msg:`写入 ${config.dist}`,
83 data:svgContent
84 });
85 }catch(err){
86 reject({
87 status:'error',
88 msg:`写入 ${config.dist}`,
89 info:err
90 });
91 };
92 });
93 }
94
95 //其它格式(jpg、jpeg、png)处理
96 else{
97 //得到原始文件大小,好作比较
98 let originalSize = m.fs.readFileSync(config.src).length,
99 useList = undefined,
100 imgmini = (optimization,callback) => {
101 //gif压缩选项,如果不是gif则不需要
102 if(extension === '.gif'){
103 useList = [
104 m.imagemin_gifsicle({
105 optimizationLevel:3,
106 interlaced:false,
107 colors:200
108 })
109 ];
110 };
111 m.imagemin([config.src],'',{
112 plugins:[
113 m.imagemin_jpegrecompress({
114 quality:'high',
115 accurate:true,
116 method:optimization,
117 min:40,
118 max:90,
119 loops:6
120 }),
121 m.imagemin_pngquant({
122 nofs:false,
123 speed:1,
124 quality:'0-100'
125 })
126 ],
127 use:useList
128 }).then(result => {
129 if(typeof callback === 'function'){
130 callback(result);
131 };
132 });
133 };
134
135 //尝试使用ssim方式先压缩,如果压缩结果没有变小则进行深层压缩
136 imgmini('ssim',result => {
137 let img = result[0].data,
138 imgSize = img.length;
139
140 //新图片如果小于原始结果则保存结果
141 if(imgSize < originalSize){
142 //写入新的压缩文件
143 m.fs.ensureDir(distDir,err => {
144 if(err){
145 reject({
146 status:'error',
147 msg:`${distDir} 创建失败`,
148 infor:err
149 });
150 };
151 try{
152 m.fs.writeFileSync(config.dist,img);
153 resolve({
154 status:'success',
155 msg:`写入 ${config.dist}`,
156 data:img
157 });
158 }catch(err){
159 reject({
160 status:'error',
161 msg:`写入 ${config.dist}`,
162 info:err
163 });
164 };
165 });
166 }else{
167 imgmini('ms-ssim',result => {
168 let img = result[0].data,
169 imgSize = img.length;
170
171 //写入新的压缩文件
172 m.fs.ensureDir(distDir,err => {
173 if(err){
174 reject({
175 status:'error',
176 msg:`${distDir} 创建失败`,
177 infor:err
178 });
179 };
180
181 //进行深层压缩,如果依然不能优化则Copy
182 if(imgSize < originalSize){
183 try{
184 m.fs.writeFileSync(config.dist,img);
185 resolve({
186 status:'success',
187 msg:`写入 ${config.dist}`,
188 data:img
189 });
190 }catch(err){
191 reject({
192 status:'error',
193 msg:`写入 ${config.dist}`,
194 info:err
195 });
196 };
197 }else{
198 new m.copy({
199 src:config.src,
200 dist:config.dist
201 }).then(v => {
202 resolve(v);
203 }).catch(e => {
204 reject(e);
205 });
206 };
207 });
208 });
209 };
210
211 })
212
213
214 };
215 }else{
216 reject({
217 status:'error',
218 msg:`${config.src} 不是有效的 PNG|JPG|JPEG|SVG 文件`
219 });
220 };
221 });
222 }
223}
224module.exports = Compile;