美文网首页
iOS图像的压缩方式有哪些?如何计算图片加载内存中的大小?

iOS图像的压缩方式有哪些?如何计算图片加载内存中的大小?

作者: 大宝来巡山 | 来源:发表于2022-08-16 19:00 被阅读0次

开发中经常会碰到从手机相册中选择图片的需求,选择图片这个过程是一个消耗性能的过程,取决于手机图片的大小,如果手机像素非常高,图片的尺寸非常大,这个时候就会变得很消耗性能,比如一张图片5M,这个时候选择后加载的时候就会有些卡顿,内存开始大幅升高,仔细想想也没有这种必要去加载这么大的图片,所以总结了两种处理方法,提供参考

1:对图片进行压缩,iOS的API中提供了函数进行压缩,代码如下:

NSData *imageData = UIImageJPEGRepresentation(image, 0.5);

//实际开发中的例子
+(NSData *)imageData:(UIImage *)myimage
{
    NSData *data = UIImageJPEGRepresentation(myimage, 1.0);
    if (data.length>100*1024) {
        if (data.length>1024*1024) {
            //1M以及以上
            data=UIImageJPEGRepresentation(myimage, 0.1);
        }else if (data.length>512*1024) {
             //0.5M-1M
            data=UIImageJPEGRepresentation(myimage, 0.5);
        }else if (data.length>200*1024) {
            //0.25M-0.5M
            data=UIImageJPEGRepresentation(myimage, 0.9);
        }
    }
    return data; 
}

优点:在基本没有降低图片的质量的前提下,压缩图片,不改变图片的分辨率
缺点:压缩图片有一定限度,因为这是不改变分辨率的压缩。比如你想压缩图片到原来的十分之一大小,但是他最大可能只会压缩到三分之一。经测试图片最大能压到的大小和图片本身有关,每个图片各不相同

这个返回的是二进制的data值,可以通过打印知道大小确实减少了好多,通过此方法确实能优化性能,需要注意的是这个0.5,并不是说压缩到之前图片的二分之一 ,应该是个系数之类的数值(0-1),这样的话图片压缩之后性能会好很多,但是不建议这个,因为解压缩的时候很耗费性能建议使用第二种方法

2:根据image从新绘制一张新的图片出来,第一种的方法多多少少会有些失真,第二种方法是根据图片从新绘制一张出来,不会失真,只是改变图片的大小,比如之前是5000 * 5000的分辨率,这个时候你压缩后可能就只有500 * 500 ,不会失真,只会改变大小,建议使用,方法如下:

//压缩图片
+ (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize
{
    // Create a graphics image context
    UIGraphicsBeginImageContext(newSize);
    
    // Tell the old image to draw in this new context, with the desired
    // new size
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    
    // Get the new image from the context
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    
    // End the context
    UIGraphicsEndImageContext();
    
    // Return the new image.
    return newImage;
}

怎么计算图片占用内存的大小呢?

我们平时看到的png、jpg、webp这些图片格式,其实都是图片压缩格式。通过对应的算法来优化了大小以节省网络传输与本地保存所需的资源。但是当我们加载图片到内存中将要显示出来的时候是不能使用压缩格式,这样就不能显示图片了。计算机依赖每一个像素点中的数据来显示图片。例如iOS中的UIImange的每个像素点是由red+green+blue 三原色在加上alpha透明度组成的。三原色每一个的范围在0 ~ 255所以需要int8来存储一个值的大小。那么一个像素点的颜色就需要3*int8 在加上需要alpha的大小。alpha的范围是0 ~ 100 也是以int8来存储的。所以一个像素点就需要4个int8来存储,也就是一个int32的大小。

我们平时取颜色也可以看到这一点。一张图片由很多像素点组成每个像素点由rgb组成的。但是这里是取颜色可能获取不到alpha。那我们现在知道了每一个像素点的大小,得出一整张图片在内存中的大小就很容易了。width * height * int32 = 图片的内存大小。

//解释一下这里bytesPerRow这个属性的意思,苹果官方文档上是这样描述的
//bytesPerRow
//The number of bytes per row of pixels in the input image data.
if let imagea = UIImage.init(named: "ccc.png"){
      let size = imagea.cgImage.height * imagea.cgImage.bytesPerRow
}

所以bytesPerRow 返回的是一张图片一行所占用的内存大小。单位是bytes。
所以我们这里只需要在乘以图片的高度就OK了。如果要转换为kb直接在除以1024就OK了。基本就是一张图片在内存中占用的大小。以一张400 * 400的图片为例。
400 * (400 * 4) / 1024 = 625KB
其中400*4 = bytesPerRow的值

参考链接:https://www.jianshu.com/p/4d80cf8b63c5

相关文章

  • iOS图像的压缩方式有哪些?如何计算图片加载内存中的大小?

    开发中经常会碰到从手机相册中选择图片的需求,选择图片这个过程是一个消耗性能的过程,取决于手机图片的大小,如果手机像...

  • 2021 - OC(一)

    1、ios一个对象占用多少字节? 2、如何计算图片加载内存中占用大小? 3、VC生命周期 4、多个网络请求完毕执行...

  • iOS 加载高清大图片

    苹果官方加载大图片例子 首先得知道图片加载到内存中的大小怎么计算 如果是位图,则位图多大则加载到内存中所占用的大小...

  • 图片内存占用问题

    测试数据 (测试文件格式为PNG) 结论 iOS图片加载到内存中,占用内存大小为图片宽度 * 图片高度 * 4。e...

  • iOS内存分析上-图片加载内存分析

    iOS内存分析上-图片加载内存分析 iOS内存分析上-图片加载内存分析

  • 超大图片的显示:BitmapRegionDecoder

    不少安卓开发者都有图片加载的处理经验,比如通过压缩节省图片加载中对内存的消耗。我们经常做的是把一张1280之类大小...

  • SDWebImage和图片压缩、缓存

    iOS中的图片加载 加载方式 imageWithContentsOfFile:+图片路径([[NSBundle m...

  • UIImage的缓存(内存管理)

    两种方式加载本地图片 通过imageNamed:方法加载图片 用过这种方式加载图片,一旦图片加载到内存中,那么就不...

  • [iOS] 图片优化

    WWDC2018 图像最佳实践 iOS 处理图片的一些小 Tip 谈谈 iOS 中图片的解压缩 WWDC 2018...

  • Android多图片压缩

    获取手机本地图片地址,先进行尺寸压缩之后加载到内存,进行循环质量压缩,图片控制在200k大小(个人建议),将数据流...

网友评论

      本文标题:iOS图像的压缩方式有哪些?如何计算图片加载内存中的大小?

      本文链接:https://www.haomeiwen.com/subject/tqhdgrtx.html