生活随笔
收集整理的這篇文章主要介紹了
app后端设计(12)--图片的处理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
app上線后,不斷接受用戶的反饋,于是,反饋非常差的情況下,都會有app的改版。
?
一旦app的改版,都會有比較大的UI改動,一改動UI,那么圖片的尺寸也就必須要改變。
?
在app后端設計(1)—api(http://blog.csdn.net/newjueqi/article/details/14053733)這篇文章中,我提到過app后臺圖片處理的一個基本原則,數據庫中只保存原圖的路徑。對于同一張圖片來說,針對不同機型,不同app版本所需要的不同尺寸,使用動態生成的策略,大體思路如下:
?
(1)??????在圖片的url末尾加上參數,聲明需要生成的圖片的新的尺寸,例如:戶端需要圖片(http://www.baidu.com/img/bdlogo.gif)的80*80的尺寸,則在圖片的路徑加上寬和高的參數(類似于CDN的機制) http://www.baidu.com/img/bdlogo.gif?w=80&h=80
(2)??????服務器接收到圖片的請求,先在緩存中查找這個尺寸的圖片是否已經生成,如果已經在緩存中有記錄,則不用重新生成。
(3)??????如果該尺寸的圖片還沒生成,則生成新的圖片尺寸,并把新生成的圖片路徑放在緩存中。
?
?
在app整個系統架構中,圖片應該有兩層緩存:
(1)??????app本地的圖片緩存,當app中沒有該圖片時,才去服務取
(2)??????服務器的圖片緩存,記錄圖片不同尺寸的保存路徑
?
我的建議是,如果不差錢,直接使用七牛的云存儲的服務吧,云存儲不但可以加速圖片的下載上傳,也能實現圖片的大量操作。要知道,速度才是用戶體驗最直接的部分。
?
如果真的要自己實現圖片的裁切,那么要考慮到圖片操作是非常消耗CPU,內存,和大量的磁盤IO,所以在選擇圖片處理工具要慎重!!!
?
推薦使用GraphicsMagick,一個久經考驗的圖片處理軟件,支持多個平臺,而且支持多種語言的客服端。GraphicsMagick是ImageMagick的一個分支,相對于ImageMagick而言,TA處理速度更快,消耗資源更少,并且大的圖片處理網站,如 Flickr and Etsy? 已經在使用TA了。
?
使用GraphicsMagick時,最折騰的是怎么配GraphicsMagick環境,查閱了大量的文章,都注明在Linux下不能使用cmd.setSearchPath(path); ,但經過我實驗,是可以的,而且配了這個的話,可以讓linux和win下都運行同一段代碼,只要把path放在配置文件中就好了。
?
下面我寫的GraphicsMagick+Im4java圖片裁剪的工具類,
?
?
?
[java] ?view plaincopy
package?com.bmob.worker.image;?? ?? import?java.awt.image.BufferedImage;?? import?java.io.FileInputStream;?? import?java.io.FileNotFoundException;?? import?java.io.IOException;?? import?java.io.InputStream;?? import?java.util.concurrent.ExecutionException;?? ?? ?? ?? public?class?Image?{?? ?? ???? ????public?static?int?DefineWidth=1;??? ????public?static?int?DefineHeight=2;??? ????public?static?int?DefineLong=3;??? ????public?static?int?DefineShort=4;??? ????public?static?int?MaxWidthHeight=5;??? ????public?static?int?DefineWidthHeight=6;??? ?????? ???? ????public??String?resize(int?mode,?String?src,String?desc,?int?width,?int?height,?int?maxFrame,?int?minFrame)?throws?Exception?{?? ?????????? ????????String?str="";?? ?????????? ????????BHPApplication.init();?? ?????????? ???????? ????????ConvertCmd?cmd?=?this.getCmd();?? ????????IMOperation?op?=null;?? ????????if(?mode==Image.DefineWidth?){?? ????????????op=this.resizeDefineWidth(?src,desc,?width,?height);?? ????????}else?if(?mode==Image.DefineHeight?){?? ????????????op=this.resizeDefineHeight(?src,desc,?width,?height);?? ????????}else?if(?mode==Image.DefineLong?){?? ????????????op=this.resizeDefineLong(?src,desc,?maxFrame);?? ????????}else?if(?mode==Image.DefineShort?){?? ????????????op=this.resizeDefineShort(?src,desc,?minFrame);?? ????????}else?if(?mode==Image.MaxWidthHeight?){?? ????????????op=this.resizeMaxWidthHeight(?src,desc,?width,?height);?? ????????}else?if(?mode==Image.DefineWidthHeight?){?? ????????????op=this.resizeDefineWidthHeight(?src,desc,?width,?height);?? ????????}?? ?????????? ????????cmd.run(op);?? ?????????? ????????return?str;?? ????}?? ?????? ???? ????public??IMOperation?resizeDefineWidth(String?src,String?desc,?int?width,?int?height){?? ????????IMOperation?op?=?new?IMOperation();?? ????????op.addImage(src);?? ????????op.resize(width,null);?? ????????op.addImage(desc);???????? ????????return?op;?? ????}?? ?????? ???? ????public??IMOperation?resizeDefineHeight(String?src,String?desc,?int?width,?int?height){?? ????????IMOperation?op?=?new?IMOperation();?? ????????op.addImage(src);?? ????????op.resize(null,height);?? ????????op.addImage(desc);???????? ????????return?op;?? ????}?? ?????? ???? ????public??IMOperation?resizeDefineLong(String?src,String?desc,?int?maxFrame)?throws?Exception{?? ?????????? ????????InputStream?is?=?new?FileInputStream(src); ????????BufferedImage?buff?=?ImageIO.read(is);?? ????????int?srcWidth=buff.getWidth(); ????????int?srcHeight=buff.getHeight();?? ????????is.close();? ?????????? ????????IMOperation?op?=?new?IMOperation();?? ????????op.addImage(src);?? ????????if(?srcWidth>srcHeight?){?? ????????????op.resize(maxFrame,null);?? ????????}else{?? ????????????op.resize(null,maxFrame);?? ????????}?? ?????????? ????????op.addImage(desc);???????? ????????return?op;?? ????}?? ?????? ???? ????public??IMOperation?resizeDefineShort(String?src,String?desc,?int?minFrame)?throws?Exception?{?? ?????????? ????????InputStream?is?=?new?FileInputStream(src); ????????BufferedImage?buff?=?ImageIO.read(is);?? ????????int?srcWidth=buff.getWidth(); ????????int?srcHeight=buff.getHeight();?? ????????is.close();? ?????????? ????????IMOperation?op?=?new?IMOperation();?? ????????op.addImage(src);?? ????????if(?srcWidth<srcHeight?){?? ????????????op.resize(minFrame,null);?? ????????}else{?? ????????????op.resize(null,minFrame);?? ????????}?? ????????op.addImage(desc);???????? ????????return?op;?? ????}?? ?????? ???? ????public??IMOperation?resizeMaxWidthHeight(String?src,String?desc,?int?width,?int?height){?? ????????IMOperation?op?=?new?IMOperation();?? ????????op.addImage(src);?? ????????op.resize(width,height,'!');?? ????????op.addImage(desc);???????? ????????return?op;?? ????}?? ?????? ???? ????public??IMOperation?resizeDefineWidthHeight(String?src,String?desc,?int?width,?int?height){?? ????????IMOperation?op?=?new?IMOperation();?? ????????op.addImage(src);?? ????????op.gravity("center").extent(width,?height);???? ????????op.addImage(desc);???????? ????????return?op;?? ????}????? ?????? ????public??ConvertCmd?getCmd(){?? ????????ConvertCmd?cmd?=?new?ConvertCmd(true);? ????????String?path?=?"/usr/local/GraphicsMagick/bin";? ????????cmd.setSearchPath(path);?????????? ????????return?cmd;?? ????}?? ?????? ?????? ?? }??
app后端系列文章總目錄
?
如果您覺得這系列的文章對你有所幫助,歡迎打賞。 支付寶賬號:190678908@qq.com 收款人:曾健生
?
新建了“app后端技術” 交流qq群:254659220?
總結
以上是生活随笔 為你收集整理的app后端设计(12)--图片的处理 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。