最近项目需求,需要压缩用户上传的图片到指定大小。遇到一些坑在这里分享一下。
- 查了很多资料搞来搞去其实还是只有那么几个压缩图片的方法:
<pre>UIImagePNGRepresentation(UIImage * __nonnull image);
UIImageJPEGRepresentation(UIImage * __nonnull image, CGFloat compressionQuality);
这两个方法返回NSData类型数据,可以根据data的length判断图片的文件大小。其中第二个方法的第二个参数是压缩系数,可以降低图片的质量从而降低图片的文件大小,值为0-1。
需要注意的是,图片质量降低有一个最低限度,超过这个限度之后,即使再降低压缩系数,图片大小也不会再改变
- 其次就是等比例缩放图片,这个方法可以改变图片的尺寸,代码如下:
<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;
} - 在用质量压缩方法压缩图片后获得data数据通过imageWithData:再转成UIImage图片后有个需要注意的地方,你会发现此时获得的image再转成data类型后长度会变大。查询了一些资料发现,imageWIthData方法,在将data转为图片时做了一些解压操作,所以此时文件大小变大。所以根据压缩后的data长度来判断UIImage的大小是不对的,UIImage此时的大小远远大于data。
由于解压操作的问题,造成用循环去不断逼近自己想要的图片大小的方法实现起来,效率特别低下,一张4M左右的图片想压缩到100K以下,平均需要2S+的时间,因为其中需要不断的进行data和image互相转换,这样会造成用户体验很差。
最后解决的方式是判断图片大小然后在每个区间给一个大概的比例然后进行压缩,这样的方式进行处理压缩效率会高出很多一张图片大概只需要0.05S左右的处理时间,但缺点是难以控制区间和压缩系数,在一些尺寸会出现图片稍大或稍小的情况,不过也算是在误差范围内。
最后大概是控制在图片大小为50K-160K这个大小区间。IOS相册的图片大小最大基本在6M以下,亲测过使用10M以上照片用系统方法UIImageWriteToSavedPhotosAlbum写入到相册以后,再读取图片大小,图片大小变为了3M左右,不知道系统使用的压缩方法和比例是如何控制的,值得思考
暂时没有找到更好的解决方法,同时保持效率和误差范围。
之前查资料时看到一个压缩方法采样压缩,但是没有具体细看。