Bitmap对象占用内存大小: bitmap.getByteCount()
图片所占内存大小计算方式:图片长度 x 图片宽度 x 一个像素点占用的字节数。
Android Bitmap使用的三种颜色格式:
- ALPHA_8–每个像素占1个字节,存储透明度信息,没有颜色信息。
- RGB_565–每个像素占2个字节存储颜色信息,R 5位,G 6位,B 5位,能表示2^16种颜色。
- ARGB_8888–每个像素占4个字节存储颜色信息,A R G B各一个字节,能表示2^24种颜色,还有一个字节存储透明度信息。
BitmapFactory 类提供了几种用于从各种来源创建 Bitmap 的解码方法(decodeStream()、decodeByteArray()、decodeFile()、decodeResource()等)。根据您的图片数据源选择最合适的解码方法。这些方法尝试为构造的位图分配内存,因此很容易导致 OutOfMemory 异常。每种类型的解码方法都有额外的签名,允许您通过 BitmapFactory.Options 类指定解码选项。在解码时将inJustDecodeBounds 属性设置为 true 可避免内存分配,为位图对象返回 null,但 outWidth、outHeight 和 outMimeType会被赋值。此方法可让您在构造位图并为其分配内存之前读取图片数据的尺寸和类型。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.image, options); //获取res资源的图片
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
压缩方式:
质量压缩:不改变图片尺寸的情况下,通过损失颜色精度减少图片的大小。图片的长,宽,像素都不变,bitmap所占内存大小是不会变的。
bitmap.compress(Bitmap.CompressFormat format, //图像的压缩格式;int quality, //图像压缩率,0-100。 0 压缩100%,100意味着不压缩;OutputStream stream) ; //写入压缩数据的输出流;
- CompressFormat.JPEG
- CompressFormat.PNG,因为 PNG 格式是无损的,它无法再进行质量压缩,quality这个参数就没有作用了,会被忽略,所以最后图片保存成的文件大小不会有变化;
- CompressFormat.WEBP,这个格式是 google 推出的图片格式,它会比 JPEG 更加省空间。官方表示能节省 25%-34% 的空间;
采样率压缩: 降低图像尺寸,改变图片的存储体积。
图片尺寸的修改其实就是通过修改像素数,放大的过程称之为上采样,缩小的过程称之为下采样。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
bm = BitmapFactory.decodeFile(imageFilePath, options);
设置inSampleSize的值(int类型)后,假如设为2,则宽和高都为原来的1/2,宽高都减少了,自然内存也降低了。
设置inPreferredConfig:
BitmapFactory.Options options2 = new BitmapFactory.Options();
options2.inPreferredConfig = Bitmap.Config.RGB_565;
图片大小直接缩小了一半,长度和宽度没有变,相比argb_8888减少了一半的内存。
createScaledBitmap:
bm = Bitmap.createScaledBitmap(bit, 150, 150, true);
将图片压缩成用户所期望的长度和宽度,但是这里要说,如果用户期望的长度和宽度和原图长度宽度相差太多的话,图片会很不清晰。
Matrix:
我们在自定义 View 控时随处件可见 Matrix 的身影,主要用于坐标转换映射,我们可以通过 Matrix 矩阵来控制视图的变换。
Matrix matrix = new Matrix();
matrix.setScale(0.5f, 0.5f);
bm = Bitmap.createBitmap(bit, 0, 0, bit.getWidth(),bit.getHeight(), matrix, true);