图片无损压缩
所謂有圖有真相,一圖勝萬言,圖片的視覺沖擊力、說明力和感染力非常強大。由于視頻和音頻的代價更高,網(wǎng)站通常選用圖片配合文字說明來吸引顧客。圖片可能不是網(wǎng)站的核心競爭力,但卻是一個網(wǎng)站最最基礎(chǔ)的用戶體驗。除了文學(xué)、學(xué)術(shù)等極少數(shù)網(wǎng)站之外,幾乎所有的網(wǎng)站都會豐富的圖片來裝飾網(wǎng)頁。
對于html,js,css等文件,自身通常很小且數(shù)量有限,壓縮價值并不大,況且web服務(wù)器幾乎都有g(shù)zip壓縮功能。
因此,網(wǎng)站的流量絕大多數(shù)由圖片傳輸構(gòu)成,從這個意義上講,通常的網(wǎng)站都是以圖片為主并不過分。淘寶京東這些流量巨人,主要的帶寬壓力無不來自于海量的圖片。要知道,程序本身是負責邏輯運算的,只有快慢優(yōu)劣之分,并不消耗帶寬。
無損壓縮是圖片優(yōu)化的重要步驟,顧名思義,就是在不改變圖片畫質(zhì)的前提下進行容量壓縮,圖片更小了,傳輸量就小,從而使網(wǎng)頁加載速度更快,顯性的提高了帶寬的利用率,直接提升用戶體驗。一般來說,網(wǎng)站首頁最起碼要控制在2M的紅線以內(nèi),為了不過分簡潔,同時兼顧網(wǎng)站內(nèi)容足夠豐富,理想的狀況是1M以內(nèi)。
常見的圖片格式主要是jpeg和png,Linux下對應(yīng)的無損壓縮工具是jpegoptim和optipng
jpegoptim 是一個C語言寫的無損壓縮軟件,效率比較高。我已經(jīng)在生產(chǎn)環(huán)境使用,每天處理圖片約10G-30G,根據(jù)粗測,每秒大約能處理30張圖片,1個小時能處理大約10w張圖片,圖片優(yōu)化后體積減少約10% ,經(jīng)濟效益比較可觀。
直接運行命令(jpegoptim xx.jpg),如果圖片已被壓縮,則跳過,如可壓縮,則會默認覆蓋圖片源文件。
參數(shù) -p 可以保證源文件壓縮后的屬性不變(權(quán)限、屬主和時間戳),
參數(shù) -q 可以省略屏幕輸出,在后臺安靜壓縮。
注意:jpegoptim 在1.3.1版本之前有個bug,-p 參數(shù)僅僅保留時間戳不變,權(quán)限和屬性為600和當前操作用戶。
有一臺圖片服務(wù)器,上面都有海量的圖片,主要圖片格式都是jpg的。
由于是海量文件,第一時間想到了for循環(huán),結(jié)果因為文件列表過于龐大,不得不放棄。
最后找到的辦法是用find + exec
| 1 2 3 | folder=/webroot/images find?$folder/$(date?+%m%d) -type?f -iname *.jpg \ ????????-exec?/usr/sbin/jpegoptim?-q -p {} \; |
這個腳本可以在晚上定期跑。也可以考慮用inotify工具做實時壓縮。
update 2014-01-15
上面的腳本是單線程的,如果一天的圖片實在是太多,可以接著考慮多線程腳本,并發(fā)壓縮,提高效率,代價是服務(wù)器較高的負載壓力,主要是CPU和IO。
假設(shè)目錄結(jié)構(gòu)是按照日期分布的,如下:
| 1 2 3 4 5 | webroot/images/2014/0115/09 webroot/images/2014/0115/10 webroot/images/2014/0115/11 webroot/images/2014/0115/12 webroot/images/2014/0115/13 |
那么并行腳本應(yīng)該這么寫。
| 1 2 3 4 5 6 7 8 9 10 11 12 | #!/usr/bin/env bash folder=/webroot/images if?[-d $folder/$(date?+%m%d) ];then ????for?hour?in?`ls?$folder/$(date?+%m%d)`; ????????do ????????find?$folder/$(date?+%m%d)/$hour -type?f -iname *.jpg \ ????????????-exec?/usr/sbin/jpegoptim?-q -p {} \; ????????done ????else ????????echo?$folder/$(date?+%m%d) is not exsit. ????????exit?0 fi |
一天工作時間有8個小時,webroot/images/2014/0115/下至少有6-8個,多至10多個子目錄,
說實話,我還真擔心那么多線程會搞垮服務(wù)器,因為jpegoptim 確實有點耗CPU和磁盤IO,
有沒有辦法控制線程數(shù)呢?有,時間數(shù)除以線程數(shù),取余數(shù),
如果線程數(shù)是2,那么任意大于2的正整數(shù)除以2,余數(shù)只會是0和1
同理,如果線程數(shù)是3,那么任意大于3的正整數(shù)除以3,余數(shù)只會是0,1,2
在shell中,11取余數(shù)的辦法是 echo $((11%2))
沒空寫了,自己想吧。
update 2014-04-22
更新jpegoptim 版本為1.3.1
圖片其實沒有我們眼睛看到的那么簡單,背后還有很多文字信息,大致有:
EXIF:照片拍攝時的各種條件,比如光圈、快門、曝光度、相機品牌、拍攝時間等
IPTC:作者、版權(quán)、字幕、細節(jié)描述等
COMMENT:注釋
一般來說,這些都是附著在圖片元數(shù)據(jù)之上的信息,刪除它們并不影響圖片畫質(zhì),
“圖片瘦身”的辦法如下
| 1 | jpegoptim -p --strip-exif --strip-iptc? --strip-com? xxx.jpg |
本文轉(zhuǎn)自 紫色葡萄 51CTO博客,原文鏈接:http://blog.51cto.com/purplegrape/1283203,如需轉(zhuǎn)載請自行聯(lián)系原作者
總結(jié)
- 上一篇: PHP类的原理
- 下一篇: [转载]找回被误删的VISTA“显示桌面