目录
Bitmap 占用内存大小计算
Bitmap | Drawable | InputStream | Byte[] 之间进行转换
Bitmap 相关方法
BitmapFactory 工厂类
Bitmap 占用内存大小计算
Bitmap 作为位图,需要读入一张图片中每一个像素点的数据,其主要占用内存的地方也正是这些像素数据。对于像素数据总大小,我们可以猜想:像素总数量 * 每个像素的字节大小,而像素总数量在矩形屏幕表现下,应该是:横向像素数量 * 纵向像素数量,结合得到:
Bitmap 内存占用 = 像素数据总大小 = 横向像素数量 * 纵向像素数量 * 每个像素的字节大小
1920 * 1080 分辨率的图片,占多少内存?
1920 * 1080 占用内存 == 1920 * 1080 * 1个像素占用内存大小
1个像素占多少内存?
单个像素的字节大小由 Bitmap 的一个配置的参数 Config 来决定。
Bitmap 中,存在一个枚举类 Config,定义了 Android 中支持的 Bitmap 配置:
Config | 占用字节大小(Byte) | 说明 |
ALPHA_8(1) | 1 | 单透明通道 |
RGB_565(3) | 2 | 简易 RGB 色调 |
ARGB_4444(4) | 2 | 已废弃 |
ARGB_8888(5) | 4 | 24位真彩色 |
RGBA_F16(6) | 8 | Android 8.0新增(更丰富的色彩表现HDR) |
HARDWARE | Special | Android 8.0新增(Bitmap 直接存储在 graphic memory) |
Bitmap | Drawable | InputStream | Byte[] 之间进行转换
1. Drawable/mipmap 下图片转换为 Bitmap
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dp);
Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.mipmap.dp);
2. Bitmap 转换为 Drawable
Drawable drawable = new BitmapDrawable(getResources(), bitmap1);
3. Bitmap 转换为 byte[]
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] bytes = baos.toByteArray();
4. byte[] 转换为 Bitmap
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
5. InputStream 转换成 Bitmap
InputStream is = getResources().openRawResource(id);
Bitmap bitmap = BitmapFactory.decodeStream(is);
6. InputStream 转换为 byte[]
InputStream is = getResources().openRawResource(id);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[1024 * 2];
int len = 0;
while ((len = is.read(b, 0, b.length)) != -1) {
baos.write(b, 0, len);
baos.flush();
}
byte[] bytes = baos.toByteArray();
Bitmap 相关方法
判断位图内存是否已经释放
public final boolean isRecycled()
获取位图的宽度
public final int getWidth()
获取位图的高度
public final int getHeight()
获取指定密度转换后的图像的宽度
public int getScaleWidth(Canvas canvas)
获取指定密度转换后的图像的高度
public int getScaleheight(Canvas canvas)
按指定的图片格式以及画质,将图片转换为输出流,即压缩图片
public boolean compress(CompressFormat format, int quality, OutputStream stream)
以 bitmap 为原图生成不可变得新图像,即创建新图
public static Bitmap createBitmap(Bitmap bitmap)
以 bitmap 为原图创建新的图像,指定新图像的宽高以及是否可变
public static Bitmap createScaledBitmap(Bitmap bitmap, int dstWidth, int dstHeight, boolean filter)
创建指定格式、大小的位图
public static Bitmap createBitmap(int width, int height, Config config)
以 bitmap 为原图,创建新的图片,指定起始坐标以及新图像的宽高
public static Bitmap createBitmap(Bitmap bitmap, int x, int y, int width, int height)
BitmapFactory 工厂类
1. Option 参数类
inJustDecodeBounds = true,不获取图片,不分配内存,但会会返回图片的高度信息。如果将这个值置为 true,那么在解码的时候将不会返回 bitmap,只会返回这个 bitmap 的尺寸。这个属性的目的是,如果你只想知道一个 bitmap 的尺寸,但又不想将其加载到内存时。这是一个非常有用的属性。
public boolean inJustDecodeBounds
inSampleSize 图片缩放的倍数,这个值是一个 int,当它小于 1 的时候,将会被当做 1 处理,如果大于 1,那么就会按照比例 1 / inSampleSize 缩小 bitmap 的宽和高,降低分辨率,大于 1 时这个值将会被处置为 2 的倍数。例如,width = 100, height = 100,inSampleSize = 2,那么就会将 bitmap 处理为,width = 50, height = 50,宽高将为 1/2, 像素数将为 1/4 (1/2 * 1/2).
public int inSampleSize
获取图片的宽度值
public int outWidth
获取图片的高度值,表示这个 Bitmap 的宽和高,一般和 inJustDecodeBounds 一起使用来获得 Bitmap 的宽高,但是不加载到内存。
public int outHeight
用于位图的像素压缩比
public int inDensity
用于目标位图的像素压缩比(要生成的位图)
public int inTargetDensity
创建临时文件,将图片存储
public byte[] inTempStorage
设置为 true 时进行图片压缩,从 inDensity 到 inTargetDensity
public boolean inScaled
当存储 Pixel 的内存空间在系统内存不足时是否可以被回收
public boolean inPurgeable
配置 Bitmap 是否可以更改,比如:在 Bitmap 上隔几个像素加一条线段
public boolean inMutable
当前屏幕的像素密度
public int inScreenDensity
2. 工厂方法
从文件读取图片
public static Bitmap decodeFile(String pathName, Options opts)
public static Bitmap decodeFile(String pathName)
从输入流读取图片
public static Bitmap decodeStream(InputStream is)
public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts)
从资源文件读取图片,res 参数直接输入 getResources()
public static Bitmap decodeResource(Resources res, int id)
public static Bitmap decodeResource(Resources res, int id, Options opts)
从数组读取图片
public static Bitmap decodeByteArray(byte[] data, int offset, int length)
public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts)
从文件读取文件,与 decodeFile 不同的是这个直接调用 JNI 函数进行读取,效率比较高
public static Bitmap decodeFileDescriptor(FileDescriptor fd)
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts)