使用系統方法UIImageJPEGRepresentation(UIimage *image,CGFloat quality)進行圖片質量壓縮,暫且叫參數quality爲壓縮比吧,取值範圍爲0~1。git
此壓縮並不是線性,當quality爲0.99時,大體壓縮到原圖片大小的1/3之內,也就是說你沒法經過此方法來把一個圖片壓縮到原大小的一半。github
弄明白這這一點剩下的就好辦了,至於實現,根據本身的需去要DIY就好了~瀏覽器
首先聲明,如下方法沒法實現對圖片大小的精確壓縮。spa
1 //以40K大小爲例,偏差1K爲例 2 UIImage * image = [UIImage imageWithData:[self compressImageWithImage:image aimWidth:200 aimLength:40*1024 accuracyOfLength:1024]];
一、質量壓縮方法實現:code
1 /** 2 * 壓縮圖片質量,返回值爲可直接轉化成UIImage對象的NSData對象 3 * aimLength: 目標大小,單位:字節(b) 4 * accuracyOfLength: 壓縮控制偏差範圍(+ / -),本方法雖然給出了偏差範圍,但實際上很難肯定一張圖片是否能壓縮到偏差範圍內,沒法實現精確壓縮。 5 */ 6 - (NSData *)compressImageWithImage:(UIImage *)image aimWidth:(CGFloat)width aimLength:(NSInteger)length accuracyOfLength:(NSInteger)accuracy{ 7 UIImage * newImage = [self imageWithImage:image scaledToSize:CGSizeMake(width, width * image.size.height / image.size.width)]; 8 9 NSData * data = UIImageJPEGRepresentation(newImage, 1); 10 NSInteger imageDataLen = [data length]; 11 12 if (imageDataLen <= length + accuracy) { 13 return data; 14 }else{ 15 NSData * imageData = UIImageJPEGRepresentation( newImage, 0.99); 16 if (imageData.length < length + accuracy) { 17 return imageData; 18 } 19 20 CGFloat maxQuality = 1.0; 21 CGFloat minQuality = 0.0; 22 int flag = 0; 23 24 while (1) { 25 CGFloat midQuality = (maxQuality + minQuality)/2; 26 27 if (flag == 6) { 28 NSLog(@"************* %ld ******** %f *************",UIImageJPEGRepresentation(newImage, minQuality).length,minQuality); 29 return UIImageJPEGRepresentation(newImage, minQuality); 30 } 31 flag ++; 32 33 NSData * imageData = UIImageJPEGRepresentation(newImage, midQuality); 34 NSInteger len = imageData.length; 35 36 if (len > length+accuracy) { 37 NSLog(@"-----%d------%f------%ld-----",flag,midQuality,len); 38 maxQuality = midQuality; 39 continue; 40 }else if (len < length-accuracy){ 41 NSLog(@"-----%d------%f------%ld-----",flag,midQuality,len); 42 minQuality = midQuality; 43 continue; 44 }else{ 45 NSLog(@"-----%d------%f------%ld--end",flag,midQuality,len); 46 return imageData; 47 break; 48 } 49 } 50 } 51 } 52
二、壓縮尺寸,傳入帶壓縮圖片對象以及目標大小便可實現。對象
1 //對圖片尺寸進行壓縮-- 2 -(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize 3 { 4 UIGraphicsBeginImageContext(newSize); 5 [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; 6 UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); 7 UIGraphicsEndImageContext(); 8 return newImage; 9 }
update[2016-2-29]:blog
今天安卓組的同事提了個bug,說壓縮到40K的圖片,下載到本地卻須要五六百K,拿到這個問題以後想了一下,壓縮到40K的數據沒有問題,上傳以後卻五六百K,在壓縮和上傳的過程當中確定出了什麼問題,因爲上傳操做是另外一個同事作的,檢查了一下代碼才發現上傳的PNG格式的圖片,問題極可能就在這裏了。圖片
由於壓縮事後把NSData使用imageWithData:轉成了UIImage對象,這一下就把40K左右的圖片轉成了一兩百K的UIImage對象,上傳以前須要把UIImage對象轉成NSData,他使用UIImagePNGRepresentation這個方法,因而data的大小又上升到五六百K。ip
因而更改方法,把壓縮好的NSData對象直接用於上傳,上傳的圖片格式使用JPEG,經過瀏覽器打開圖片驗證以後問題得以解決。這也說明了一個問題,NSData的大小不等於UIImage的大小,而png格式的圖片比同質量同分辨率的jpg和jpeg格式圖片大了數倍。get
下面分享一下項目中用於從zip中讀取圖片和壓縮切割圖片的分類,實現從zip中直接讀取文件而不解壓zip的是第三方類庫ZipZap,須要的話能夠經過pod search zipzap命令在Github上搜索,分類請點此下載。