最近項目需求,需要壓縮用戶上傳的圖片到指定大小。遇到一些坑在這里分享一下。
- 查了很多資料搞來搞去其實還是只有那么幾個壓縮圖片的方法:
<pre>UIImagePNGRepresentation(UIImage * __nonnull image);
UIImageJPEGRepresentation(UIImage * __nonnull image, CGFloat compressionQuality);
這兩個方法返回NSData類型數(shù)據(jù),可以根據(jù)data的length判斷圖片的文件大小。其中第二個方法的第二個參數(shù)是壓縮系數(shù),可以降低圖片的質(zhì)量從而降低圖片的文件大小,值為0-1。
需要注意的是,圖片質(zhì)量降低有一個最低限度,超過這個限度之后,即使再降低壓縮系數(shù),圖片大小也不會再改變
- 其次就是等比例縮放圖片,這個方法可以改變圖片的尺寸,代碼如下:
<pre>+ (UIImage )cropImage:(UIImage )image scale:(CGFloat)scale
{
CGSize newSize = CGSizeMake(image.size.widthscale, image.size.heightscale);
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
} - 在用質(zhì)量壓縮方法壓縮圖片后獲得data數(shù)據(jù)通過imageWithData:再轉(zhuǎn)成UIImage圖片后有個需要注意的地方,你會發(fā)現(xiàn)此時獲得的image再轉(zhuǎn)成data類型后長度會變大。查詢了一些資料發(fā)現(xiàn),imageWIthData方法,在將data轉(zhuǎn)為圖片時做了一些解壓操作,所以此時文件大小變大。所以根據(jù)壓縮后的data長度來判斷UIImage的大小是不對的,UIImage此時的大小遠(yuǎn)遠(yuǎn)大于data。
由于解壓操作的問題,造成用循環(huán)去不斷逼近自己想要的圖片大小的方法實現(xiàn)起來,效率特別低下,一張4M左右的圖片想壓縮到100K以下,平均需要2S+的時間,因為其中需要不斷的進(jìn)行data和image互相轉(zhuǎn)換,這樣會造成用戶體驗很差。
最后解決的方式是判斷圖片大小然后在每個區(qū)間給一個大概的比例然后進(jìn)行壓縮,這樣的方式進(jìn)行處理壓縮效率會高出很多一張圖片大概只需要0.05S左右的處理時間,但缺點是難以控制區(qū)間和壓縮系數(shù),在一些尺寸會出現(xiàn)圖片稍大或稍小的情況,不過也算是在誤差范圍內(nèi)。
最后大概是控制在圖片大小為50K-160K這個大小區(qū)間。IOS相冊的圖片大小最大基本在6M以下,親測過使用10M以上照片用系統(tǒng)方法UIImageWriteToSavedPhotosAlbum寫入到相冊以后,再讀取圖片大小,圖片大小變?yōu)榱?M左右,不知道系統(tǒng)使用的壓縮方法和比例是如何控制的,值得思考
暫時沒有找到更好的解決方法,同時保持效率和誤差范圍。
之前查資料時看到一個壓縮方法采樣壓縮,但是沒有具體細(xì)看。