使用系统方法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上搜索,分类请点此下载。