iOS图片压缩

本文探讨了iOS中图片压缩的两种方法:质量压缩和尺寸压缩。质量压缩利用苹果API,循环或二分法压缩,但对大图效果有限。尺寸压缩包括使用UIGraphics和ImageIO,后者在处理大图时更节省内存。二分法在压缩性能上优于循环压缩。文章总结了不同场景下选择合适压缩策略的建议。
摘要由CSDN通过智能技术生成

iOS图片压缩

一般图片压缩的需求
  1. 压缩到指定宽高(例如:微信图片压缩,宽或者高不超过 1280 )
  2. 压缩到指定大小(例如:微信小程序分享,图片不超过 32kb)
常规的图片压缩方法
一、质量压缩
UIImageJPEGRepresentation(image, compression);

这是苹果爸爸提供的质量压缩API:第一个参数是 目标image,第二个参数 compression 取值 0.0 ~ 1.0,理论上值越小表示图片质量越低,图片文件自然越小。

但这里有个注意点,并不是 compression 取 0,就是0b大小,取 1 就是原图:

a.首先:图片的大小是根据(图片的宽 * 图片的高 * 每一个色彩的深度)来获取的,
图片只会按照你的手机像素的分辨率 [UIScreen mainScreen].scale 来读取值。

b.其次:对于大图片来说,即使你的 compression 选的很小很小,
比如:0.0000000(n个0)001,无论多小都没有用,因为达到
一定阈值之后,就再也压不下去了,但是得到的结果还是很大,
DEMO中例子:一张13M左右的图片,处理后极限大小为551kb左右。
循环压缩的方法:
+ (UIImage *)compressImageQualityNormal:(UIImage *)image toByte:(NSInteger)maxLength
{
    CGFloat compression = 1;
    NSUInteger count = 0;
    NSData *data = UIImageJPEGRepresentation(image, compression);
    while (data.length > maxLength && compression > 0) {
        compression -= 0.01;
        count++;
        // 当压缩到某个阈值的时候,这句代码就没有效果了
        data = UIImageJPEGRepresentation(image, compression);
        NSLog(@"%@", [NSString stringWithFormat:@"压缩次数:%zd,压缩比例:%f,压缩后的图片大小:%f kb", count, compression, data.length / 1000.0]);
    }
    
    UIImage *resultImage = [UIImage imageWithData:data];
    return resultImage;
}

以下是压缩数据:

图片的原始大小:13362 kb

压缩次数 压缩比例 压缩后的图片大小
1 0.990000 5984.280000 kb
2 0.980000 5818.233000 kb
3 0.970000 5663.514000 kb
37 0.630000 2726.441000 kb
38 0.620000 2659.856000 kb
39 0.610000 2594.750000 kb
67 0.330000 925.446000 kb
68 0.320000 886.675000 kb
69 0.310000 867.404000 kb
90 0.100000 562.138000 kb
91 0.090000 561.355000 kb
92 0.080000 553.827000 kb
93 0.070000 553.236000 kb
94 0.060000 551.402000 kb
95 0.050000 551.402000 kb
96 0.040000 551.402000 kb
97 0.030000 551.402000 kb
98 0.020000 551.402000 kb
99 0.010000 551.402000 kb
100 -0.000000 551.402000 kb
换句话来说,如果要实现压缩到指定大小(比如 32k),如果是小图倒是不会有什么问题,多试几次应该能得到想要的结果,如果大图(比如 13M)只用压缩质量的方式,是办不到的,达到一定阈值之后(压缩比例:小于0.060000),就再也压不下去了。

当然,这个方法是有问题的,总共压缩了 100 次,循环次数过多,效率低,耗时长

如果你得到的图片压缩的需求,是保证尺寸不变的情况下,尽可能压到最小,自然只需要循环压缩就好,不过有更好的实现方式,那就是 二分法

+ (UIImage *)compressImageQualityDichotomy:(UIImage *)image toByte:(NSInteger)maxLength
{
    CGFloat compression = 1;
    NSData *data = UIImageJPEGRepresentation(image, compression);
    if (data.length < maxLength) return image;
    CGFloat max = 1;
    CGFloat min = 0;
    // 二分最大10次,区间范围精度最大可达0.00097657;第6次,精度可达0.015625,10次,0.000977
    for (int i = 0; i < 10; ++i) {
        compression = (max + min) / 2;
        NSLog(@"%@", [NSString stringWithFormat:@"压缩精度:%f", compression]);
        data = UIImageJPEGRepresentation(image, compression);
        if (data.length < maxLength * 0.9) {
            min = compression;
        } else if (data.length > maxLength) {
            max = compression;
        } else {
            break;
        }
    }
    UIImage *resultImage = [UIImage imageWithData:data];
    return resultImage;
}

二分最大10次即可,既可以达到压缩到阈值的效果,又能节约性能,区间范围精度最大可达0.00097657;第6次,精度可达0.015625,10次,0.000977

使用二分法进行处理,比for循环依次递减**“高效”很多,而且也合理**很多,第10次就达到了单纯的for循环的99次的效果。

次数 压缩比例
1 0.500000
2 0.250000
3 0.125000
4 0.062500
5
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值