以前的文章——圖片優化調研之理論篇——主要以理論的東西爲主。正確選擇合適的圖片格式——無論你用Fireworks仍是Photoshop,可用預覽功能多去嘗試,選擇size最小的且確保質量(其場景與PM商定)的圖片。另外一個方面,就是無損壓縮。本篇文章主要針對自動無損壓縮,具體再囉嗦一下如何實現。php
pngout官網提供一個windows平臺客戶端版本——http://www.ardfry.com/pngoutwin/ 簡單介紹它怎麼用——html
這裏僅僅針對批量壓縮——node
這裏對common模塊(隨意舉例)進行例子解析——git
當壓縮圖片的格式選擇gif的時候(僅僅針對gif格式的圖片進行壓縮),會看到——github
全部的gif圖片均轉換爲png格式圖片,再進行無損壓縮,總體壓縮以後的結果——shell
出現一個問題,原本loading.gif是多幀動畫,卻被壓縮成了單幀png,不符合預期。所以,這裏的總體替換(gif-->png)存在必定風險,要確保排除動畫gif的壓縮。windows
在這裏,就不介紹將jpg轉換爲png的過程了(同gif),不建議這樣去作,以避免形成大量失真。數組
在來看看它的壓縮率,會看到批量壓縮節省的字節數——svn
天然就能算出總體壓縮率了。工具
《高性能網站建設進階指南》這本書的做者提供的服務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 });
能夠看到結果——
無論用node或者php或者shell,總體的實現思路均是循環遍歷圖片,而後使用合適的命令行工具實現無損壓縮。在這兒就不繼續說了。