在app中,如果上传图片不进行压缩处理,有些高清大图就会上传得很慢,如果用户量大,同一时间内有大量用户上传高清大图,则容易阻塞服务器,而且其他用户查看图片时会出现下载慢费流量的问题,而进行了压缩处理,则可以加快图片上传下载的速度,还可以节省用户流量。
iOS中有两种方式可以对图片进行压缩:压缩图片质量,压缩图片尺寸
压缩图片质量(尺寸不变,质量改变)
NSData *data = UIImageJPEGRepresentation(image, compression);
UIImage *resultImage = [UIImage imageWithData:data];
压缩图片尺寸(尺寸改变,质量不变)
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
压缩图片到指定大小的设计:
采用压缩图片质量和压缩图片尺寸两种方法结合,先压缩图片质量再压缩图片尺寸,压缩图片质量时,采用二分法来提高压缩效率,同时由于有时候图片压缩到一定程度后,再次压缩并不会减少图片数据,所以每次压缩后都和上一次的图片大小进行对比,如果变化不大,则退出循环,或达到目标大小时退出循环。压缩图片尺寸则采用绘图的方式,这样图片质量不会丢失,同时对目标大小和当前数据大小的系数进行开根,这样当前数据大小离目标数据大小越大,图片尺寸减小得越大,减小循环次数提供绘图效率,当然,压缩质量和压缩尺寸都是在子线程中进行,尽量减少主线程压力
效果
这个是20M大图,被压缩到87kb,从压缩开始到完成用时1秒
image.png
image.png
这个是800多KB的图片,被压缩到65KB,从压缩开始到完成用时0.1秒
image.png
image.png
代码:
-(void)compressWithMaxLengthKB:(NSUInteger)maxLengthKB Block :(void (^)(NSData *imageData))block{
if (maxLengthKB <= 0 || [self isKindOfClass:[NSNull class]] || self == nil) block(nil);
maxLengthKB = maxLengthKB*1024;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
CGFloat compression = 1;
NSData *data = UIImageJPEGRepresentation(self, compression);
NSLog(@"初始 : %ld KB",data.length/1024);
if (data.length < maxLengthKB){
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"压缩完成: %zd kb", data.length/1024);
block(data);
});
return;
}
//质量压缩
CGFloat scale = 1;
CGFloat lastLength=0;
for (int i = 0; i < 7; ++i) {
compression = scale / 2;
data = UIImageJPEGRepresentation(self, compression);
NSLog(@"质量压缩中: %ld KB", data.length / 1024);
if (i>0) {
if (data.length>0.95*lastLength) break;//当前压缩后大小和上一次进行对比,如果大小变化不大就退出循环
if (data.length < maxLengthKB) break;//当前压缩后大小和目标大小进行对比,小于则退出循环
}
scale = compression;
lastLength = data.length;
}
NSLog(@"压缩图片质量后: %ld KB", data.length / 1024);
if (data.length < maxLengthKB){
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"压缩完成: %zd kb", data.length/1024);
block(data);
});
return;
}
//大小压缩
UIImage *resultImage = [UIImage imageWithData:data];
NSUInteger lastDataLength = 0;
while (data.length > maxLengthKB && data.length != lastDataLength) {
lastDataLength = data.length;
CGFloat ratio = (CGFloat)maxLengthKB / data.length;
NSLog(@"Ratio = %.1f", ratio);
CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)),
(NSUInteger)(resultImage.size.height * sqrtf(ratio)));
UIGraphicsBeginImageContext(size);
[resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
data = UIImageJPEGRepresentation(resultImage, compression);
NSLog(@"绘图压缩中: %ld KB", data.length / 1024);
}
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"压缩完成: %zd kb", data.length/1024);
block(data);
});return;
});
}










网友评论