圖片優化調研之實踐篇

前言

以前的文章——圖片優化調研之理論篇——主要以理論的東西爲主。正確選擇合適的圖片格式——無論你用Fireworks仍是Photoshop,可用預覽功能多去嘗試,選擇size最小的且確保質量(其場景與PM商定)的圖片。另外一個方面,就是無損壓縮。本篇文章主要針對自動無損壓縮,具體再囉嗦一下如何實現。php

實踐

1.pngout客戶端實現圖片批量無損壓縮

pngout官網提供一個windows平臺客戶端版本——http://www.ardfry.com/pngoutwin/ 簡單介紹它怎麼用——html

1.1 設置壓縮圖片輸出路徑

1.2 選擇源圖文件夾

這裏僅僅針對批量壓縮——node

1.3 看結果

這裏對common模塊(隨意舉例)進行例子解析——git

 

當壓縮圖片的格式選擇gif的時候(僅僅針對gif格式的圖片進行壓縮),會看到——github

全部的gif圖片均轉換爲png格式圖片,再進行無損壓縮,總體壓縮以後的結果——shell

出現一個問題,原本loading.gif是多幀動畫,卻被壓縮成了單幀png,不符合預期。所以,這裏的總體替換(gif-->png)存在必定風險,要確保排除動畫gif的壓縮。windows

在這裏,就不介紹將jpg轉換爲png的過程了(同gif),不建議這樣去作,以避免形成大量失真。數組

在來看看它的壓縮率,會看到批量壓縮節省的字節數——svn

天然就能算出總體壓縮率了。工具

2.smushit

《高性能網站建設進階指南》這本書的做者提供的服務http://www.smushit.com/ysmush.it/ 這裏使用node-smushit模塊實現批量壓縮——

  1 var minifier = require('node-smushit');
  2 var log4js = require('log4js');
  3 var logger = log4js.getLogger();
  4 
  5 var util = (function() {
  6     var src_total_size = 0;     // 記錄輸入圖片總大小
  7     var dest_total_size = 0;    // 記錄輸出圖片總大小
  8     var total_percent;          // 記錄總的壓縮率
  9 
 10     var total = 0;              // 圖片總個數
 11     var saving = 0;             // 須要壓縮的圖片總個數
 12 
 13     // 遞增圖片總個數
 14     var increaseTotal = function() {
 15         total = total + 1;
 16     };
 17 
 18     // 獲取圖片總個數
 19     var getTotal = function() {
 20         return total;
 21     };
 22 
 23     // 遞增須要壓縮的圖片總個數
 24     var increaseSaving = function() {
 25         saving = saving + 1;
 26     };
 27 
 28     // 獲取須要壓縮的圖片總個數
 29     var getSaving = function() {
 30         return saving;
 31     };
 32 
 33     // 遞增輸入圖片大小
 34     var increaseSrcTotalSize = function(itemSize) {
 35         src_total_size = src_total_size + itemSize;
 36     };
 37 
 38     // 獲取輸入圖片總大小
 39     var getSrcTotalSize = function() {
 40         return src_total_size;
 41     };
 42 
 43     // 遞增輸出圖片總大小
 44     var increaseDestTotalSize = function(itemSize) {
 45         dest_total_size = dest_total_size + itemSize;
 46     };
 47 
 48     // 獲取輸出圖片總大小
 49     var getDestTotalSize = function() {
 50         return dest_total_size;
 51     };
 52 
 53     // 計算壓縮率
 54     var computeTotalPercent = function() {
 55         total_percent = ((src_total_size - dest_total_size) / src_total_size * 100).toFixed(2) + '%';
 56     };
 57 
 58     // 獲取壓縮率
 59     var getTotalPercent = function() {
 60         return total_percent;
 61     };
 62 
 63     // 壓縮圖片與原圖片的大小差值,即節省了多少字節
 64     var getReduce = function() {
 65         return src_total_size - dest_total_size;
 66     };
 67 
 68     return {
 69         getTotal: getTotal,
 70         getSaving: getSaving,
 71         getSrcTotalSize: getSrcTotalSize,
 72         getDestTotalSize: getDestTotalSize,
 73         getTotalPercent: getTotalPercent,
 74         increaseTotal: increaseTotal,
 75         increaseSaving: increaseSaving,
 76         increaseSrcTotalSize: increaseSrcTotalSize,
 77         increaseDestTotalSize: increaseDestTotalSize,
 78         computeTotalPercent: computeTotalPercent,
 79         getReduce: getReduce
 80     };
 81 })();
 82 
 83 // 打印日誌
 84 var printResult = function() {
 85     logger.info('圖片總個數:' + util.getTotal());
 86     logger.info('無損壓縮圖片總個數:' + util.getSaving());
 87 
 88     logger.info('輸入須要壓縮的圖片總大小:' + util.getSrcTotalSize() + ' Bytes');
 89     logger.info('輸出通過壓縮的圖片總大小:' + util.getDestTotalSize() + ' Bytes');
 90     logger.info('-------------共節省大小:' + util.getReduce() + ' Bytes');
 91     logger.info('壓縮率(相對輸入圖片總大小):' + util.getTotalPercent());
 92 };
 93 
 94 // 這裏能夠指定多個圖片文件夾目錄,用數組表示
 95 minifier.smushit(['./static/images/', './widget/'], {
 96 
 97     // 循環遍歷文件夾及其子目錄中的圖片設置
 98     // true: 遍歷循環
 99     // false: 非遍歷循環
100     recursive: true,
101 
102     // 每張圖片開始壓縮
103     onItemStart: function(item) {
104         // 這裏的item是每張輸入圖片的源地址
105     },
106 
107     // 每張圖片完成壓縮
108     onItemComplete: function(e, item, response) {
109         /**
110          * response的格式——
111          * {
112          *      src: '',
113          *      src_size: ,
114          *      dest: '',
115          *      dest_size: ,
116          *      percent: ,
117          *      id: ''
118          * }
119          */
120 
121         // 過濾掉svn目錄中的文件
122         if (/.svn/g.test(response.src) === false) {
123             util.increaseTotal();
124 
125             /*
126              * 注意:
127              * 當檢測到某些圖片已經沒法壓縮或者已經通過壓縮,此時response.src_size的值是undefined
128              * 所以在這兒加入一層過濾,針對能夠壓縮的圖片進行統計
129              */
130             if (response.src_size && response.dest_size) {
131                 util.increaseSaving();
132                 util.increaseSrcTotalSize(response.src_size);
133                 util.increaseDestTotalSize(response.dest_size);
134             }
135         }
136 
137     },
138 
139     // 全部圖片完成壓縮
140     // 這裏的reports變量記錄全部圖片的源地址、源大小、目標地址、目標大小、壓縮率等信息的列表
141     onComplete: function(reports) {
142 
143         // 統計壓縮率
144         util.computeTotalPercent();
145 
146         // 打印統計日誌
147         printResult();
148     }
149 });

能夠看到結果——

3. 其餘實現方案

無論用node或者php或者shell,總體的實現思路均是循環遍歷圖片,而後使用合適的命令行工具實現無損壓縮。在這兒就不繼續說了。

相關文章
相關標籤/搜索