做網站往往需要處理各種各樣的圖片,對于jdk自帶的一套圖片處理庫,他的特點是穩定簡單,但是對圖片處理來說,性能確實很不咋的!
??? ??? 于是我轉向了以C++處理為核心的java處理包—— JMagick+ ImageMagick 。jmagick是一個開源的API,利用JNI(Java Native Interface)技術實現了對ImageMagickAPI 的Java訪問接口,因此也將比純Java實現的圖片操作函數在速度上要快。實地測試后發現,速度果然提高了不少,但是質量卻大大下降了,在大量測試數據 下,每生成100張圖片約會有5張圖片生成出現錯誤,還會出現down機的情況。對于一個商業應用來說,這個是絕對不可以接受的,于是對jmagick的 研究暫放一段時間。
??? ??? 經過韓boss指導,我轉向了 GraphicsMagick+im4java 的研究,輸入關鍵詞google一下,很容易就可以找到
http://javantsky.iteye.com/blog/747807
,這篇博客,文章介紹GraphicsMagick+im4java 性能高,運行穩定!
??? ??? 于是我開始了對GraphicsMagick+im4java實際研究:
??? ??? 個人感覺im4java就是graphicsmagick的外面包裝了一層“紙”,一個java轉換的命令行輸出工具,其api也基本沒有參考價值(有些 與實際不符的地方),GraphicsMagick+im4java的核心在于GraphicsMagick。
??? ??? 作為一個縮放+切割功能的實現,可以使用
- gm?convert?input.jpg?-thumbnail?100x100^?-gravity?center?-extent?100x100?output.jpg??
gm convert input.jpg -thumbnail 100x100^ -gravity center -extent 100x100 output.jpg
???? ??? 這條命令,經過測試發現,thumbnail命令的效率還不如原有java實現的效率,可能用它來實現這么簡單的功能是高射炮打蚊子了,關于GraphicsMagick各項參數的使用的文章,網上實在是少之又少,于是只能靠自己了!
??????? 我找到了所有和縮放有關的命令,經過一一驗證,最終選擇了sample命令。相比最初的純java實現,內存節省了約70%,CPU效率提高了約80%, 耗費時間約節省了72%,下面為我找到的所有縮放有關的GraphicsMagick命令的測試數據:
Graphics+im4java性能對比:
??? ??? 記錄一(其中內存和CPU為觀測數據):
??? ??? 原有java實現:
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:1185M(共)
??? ??? ??? CPU:170%(共)(按雙核)
??? ??? ??? 耗時:162,875ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:36.1K
??? ??? thumbnail命令實現:
- gm?convert?input.jpg?-thumbnail?600x600^?-gravity?center?-extent?600x600?output.jpg??
gm convert input.jpg -thumbnail 600x600^ -gravity center -extent 600x600 output.jpg
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:150M/線程
??? ??? ??? CPU:9%/線程
??? ??? ??? 耗時:193,423ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:78.5K
??? ??? geometry命令實現:
- gm?convert?input.jpg?-geometry?600x600^?-gravity?center?-extent?600x600?output.jpg??
gm convert input.jpg -geometry 600x600^ -gravity center -extent 600x600 output.jpg
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:50M/線程
??? ??? ??? CPU:9%/線程
??? ??? ??? 耗時:94,518ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:101.8K
??? ??? resize命令實現:
- gm?convert?input.jpg?-resize?600x600^?-gravity?center?-extent?600x600?output.jpg??
gm convert input.jpg -resize 600x600^ -gravity center -extent 600x600 output.jpg
? ??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:55M/線程
??? ??? ??? CPU:13%/線程
??? ??? ??? 耗時:97,342ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:101.8K
??? ??? sample命令實現:
- gm?convert?input.jpg?-sample?600x600^?-gravity?center?-extent?600x600?output.jpg??
gm convert input.jpg -sample 600x600^ -gravity center -extent 600x600 output.jpg
? ??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:35M/線程
??? ??? ??? CPU:9%/線程
??? ??? ??? 耗時:46,541ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:117.3K
??? ??? sample(quality:50)
- gm?convert?input.jpg?-sample?600x600^?-gravity?center?-extent?600x600?-quality? 50 ?output.jpg??
gm convert input.jpg -sample 600x600^ -gravity center -extent 600x600 -quality 50 output.jpg
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:40M/線程
??? ??? ??? CPU:16%/線程
??? ??? ??? 耗時:68,839ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:47.2
??? ??? scale命令實現:
- gm?convert?input.jpg?-scale?600x600^?-gravity?center?-extent?600x600?output.jpg??
gm convert input.jpg -scale 600x600^ -gravity center -extent 600x600 output.jpg
? ??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:42M/線程
??? ??? ??? CPU:8%/線程
??? ??? ??? 耗時:68,778ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:99.2K
??? ??? 在sample命令下,可以通過修改quality參數的值,來修改輸出圖片質量,改變輸出圖片大小。以下為我的測試數據:
??? ??? 記錄二:
??? ??? ??? sample對比(無quality設置):
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:32(\)M/線程
??? ??? ??? CPU:9%/線程
??? ??? ??? 耗時:46,659ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:117.3K
??? ??? ??? sample(quality:50)
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:28M/線程
??? ??? ??? CPU:9%/線程
??? ??? ??? 耗時:40,549ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:48.8
??? ??? ??? sample(quality:60)
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:35M(\)/線程
??? ??? ??? CPU:8%(\)/線程
??? ??? ??? 耗時:45,647ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:53.3
??? ??? ??? sample(quality:75)
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:30M(\)/線程
??? ??? ??? CPU:9%(\)/線程
??? ??? ??? 耗時:45,719ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:65.6
??? ??? ??? sample(quality:85)
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:32M(\)/線程
??? ??? ??? CPU:8%(\)/線程
??? ??? ??? 耗時:46,510ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:84.5
??? ??? ??? sample(quality:95)
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:34M(\)/線程
??? ??? ??? CPU:8%(\)/線程
??? ??? ??? 耗時:47,650ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:156.0
??? ??? ??? sample(quality:100)
??? ??? ??? 圖片大小:2.5M(2592x1944)
??? ??? ??? 內存:34M(\)/線程
??? ??? ??? CPU:11%(\)/線程
??? ??? ??? 耗時:50,469ms/200張(線程池10)
??? ??? ??? 輸出圖片大小:298.1
- ConvertCmd?cvcmd?=?new?ConvertCmd();??
- Operation?op?=?new?Operation();??
- op.addImage();??
- op.addRawArgs( "-sample" ,? "600x600^" );??
- op.addRawArgs( "-gravity" ,? "center" );??
- op.addRawArgs( "-extent" ,? "600x600" );??
- op.addRawArgs( "-quality" ,? "100" );??
- op.addImage();??
- ??
- cvcmd.run(op,?srcImg,?desImg);??
ConvertCmd cvcmd = new ConvertCmd(); Operation op = new Operation(); op.addImage(); op.addRawArgs("-sample", "600x600^"); op.addRawArgs("-gravity", "center"); op.addRawArgs("-extent", "600x600"); op.addRawArgs("-quality", "100"); op.addImage(); cvcmd.run(op, srcImg, desImg);
? ? ? ? 這是我從文小貓童鞋那里找到的一張她自制的美食圖片,源圖像文件像素為1944x2592,處理后為600x600;
??????? 由于個人能力有限,歡迎大家指出不足,提出更好的解決方案!
???????
??? ??? im4java官方網站:
??? ???
http://im4java.sourceforge.net/index.html
??? ??? im4java的api:
??? ???
http://im4java.sourceforge.net/api/
??? ??? graphicsmagick的官方網站:
??? ???
http://www.graphicsmagick.org/index.html
??? ??? graphicsmagick的命令行參數解析:
??? ???
http://www.graphicsmagick.org/utilities.html
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
