关于图片本身大小、格式、内存、压缩相关知识

首先感谢这篇博客,给了我很大启发:Android中一张图片占据的内存大小如何计算

下面总结我的一些思考和收获:

1、图片都有尺寸,这里尺寸用的是图片属性的分辨率表示:1600*1600,代表宽和高均有1600个像素点,而一个像素点ARGB四个通道,每个通道共有256个值,在计算机存储中占8位,即1个字节,那么这张图片实际大小就是1600*1600*4/1024/1024=9.76MB,但你点开图片发现它的大小却只有几十K,这是怎么回事呢?其实是对原图片进行了压缩,不同格式的图片代表对原图片压缩的策略不同,举两个例子,jpg格式为无损压缩,它是利用了人眼睛在观察颜色缺失的事物时会自动用周围最近颜色填补的特性,所以丢失部分像素信息 。而png则是采用一种算法,通过记录原颜色信息的特征来简化信息,比如记录重复的像素的起始位置,从而实现减少信息量

2、但在android中,图片还是会解析成位图信息进行展示的,那是不是图片内存大小其实就还是:分辨率大小*像素呢,是的,不过这里BitmapFactory.decodeResource()方法比较特殊,它会根据res下不同dpi目录,对其中的图片分辨率做转换(其它decodeXxx方法都是按照原图分辨率计算):

设备的高度=原始高度*(设备dpi/目录对应的dpi)

设备的宽度=原始宽度*(设备dpi/目录对应的dpi)

3、综上,我们想要减少图片占用内存的大小,那么就需要从减小图片分辨率(即图片大小)和像素入手,减小分辨率可以通过BitmapFactory.Options.inSampleSize属性进行设置,表示将图片宽和高等比例缩小多少倍(至于缩小后像素颜色值如何排列和计算我就不清楚了,这是native层的逻辑);而减少像素大小可以通过设置处理图片的格式,我们一般默认采用的是ARGB_8888占2个字节,如果不需要透明度,可以设置RGB_565只需要2个字节,或者ARGB_4444,也需要2个字节

4、通过给定的URL,可以直接通过BitmapFactory.decodeStream(URL.openconnection())来获取Bitmap

5、内存外存的区别:内存容量小,但读写速度快,外存容量大,但读写速度远不及内存,内存存放系统及程序运行使用,一旦断电,所有内存都会消失,而外存不会

6.Bitmap的复用,通过设置BitmapFactory.Options的inMutable为true,inBitmap属性设置为可复用的Bitmap,这样通过decodeByteArray创建Bitmap时就会复用设置的inBitmap,不过需要注意,android4.3之前被复用的Bitmap的格式必须是png或jpg,而且两者的宽高、ARGB必须相同,采样率inSampleSize必须为1;4.4-7.1版本被复用的Bitmap只要所占内存不小于新建的Bitmap即可复用;而在8.0及以上版本,Bitmap数据存储在native内存,所以不会有gc等问题

public Bitmap decodeBitmap(byte[] data, Bitmap.Config config, int targetWidth, int targetHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        //通过inJustDecodeBounds参数,先获取待生成Bitmap的尺寸信息
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(data, 0, data.length, options);
        //计算采样率        
        options.inSampleSize = calculateInSampleSize(options, targetWidth, targetHeight);                     
        options.inJustDecodeBounds = false;
        options.inMutable = true;//生成的bitmap可修改
        options.inPreferredConfig = config;
        //根据待生成Bitmap的尺寸信息,获取符合条件可复用的bitmap
        options.inBitmap = getReusableBitmap(options);
        return BitmapFactory.decodeByteArray(data, 0, data.length, options);
}

百度安全验证

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值