本文最后更新于 875 天前,其中的信息可能已经有所发展或是发生改变。
1. 占用大小
- scaledWidth = int( 原图宽度 * (设备的 dpi / 目录对应的 dpi ) + 0.5)
- scaledHeight = int( 原图高度 * (设备的 dpi / 目录对应的 dpi ) + 0.5)
- scaledWidth * scaledHeight * 4(具体Bitmap 的格式大小,如:ARGB_8888是4字节)
- 0.5是为了精度,一般直接记为 原图高度 * (设备的 dpi / 目录对应的 dpi * 原图高度 * (设备的 dpi / 目录对应的 dpi
- ARGB_8888是4字节, RGB_565是2字节
density | 1 | 1.5 | 2 | 3 | 3.5 | 4 |
densityDpi | 160 | 240 | 320 | 480 | 560 | 640 |
2. 优化调节
2.1 decodeResource()和decodeFile()
- decodeFile()用于读取SD卡上的图,得到的是图片的原始尺寸
- decodeResource()用于读取Res、Raw等资源,得到的是图片的原始尺寸 * 缩放系数
> 缩放系数 inDensity
> 在drawable非 xxdpi的目录 默认160,inTargetDensity / 160
> xxdpi的目录,根据相应的目录density inTargetDensity / xxDensity
// 手动的方式
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = 1;
options.inDensity = 160;
options.inTargetDensity = 160;
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.origin, options);
// MX4上,虽然density = 3
// 但是通过设置inTargetDensity / inDensity = 160 / 160 = 1
// 解码后图片大小为720x720
System.out.println("w:" + bitmap.getWidth()
+ ", h:" + bitmap.getHeight());
2.2 inBitmap 对象的复用
Android2.3.3 以下
推荐使用 Bitmap#recycle 方法进行 Bitmap 内存回收
Android3.0 以上
推荐的是 Bitmap 内存复用,为此引入了一个 BitmapFactory.Options.inBitmap 字段来设置打算复用的 Bitmap
2.3 LruCache和DiskLruCache
2.4 inSampleSize – 需要是2的次方
设置BitmapFactory.Options的inJustDecodeBounds为true,这样的Bitmap可以借助decodeFile方法把高和宽存放到Bitmap.Options中,但是内存占用为空(不会真正的加载图片)。有了具备高宽信息的Options
private Bitmap getRealCompressedBitmap(String pathName, int reqWidth, int reqHeight) {
Bitmap bitmap;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
int width = options.outWidth / 2;
int height = options.outHeight / 2;
int inSampleSize = 1;
while (width / inSampleSize >= reqWidth && height / inSampleSize >= reqHeight) {
inSampleSize = inSampleSize * 2;
}
options.inSampleSize = inSampleSize;
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(pathName, options);
showBitmapInfos(pathName);
return bitmap;
}
2.5 Matrix 大->小
2.6 BitmapRegionDecoder 大图加载
2.7 图片压缩
- Bitmap自带的压缩
Bitmap bitmap = getZoomImage(BitmapFactory.decodeFile(imagePath), 400);
// 压缩只是改变文件存储的大小,不会改变内存占用大小
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, fos);
- 系统裁剪
private void CropTheImage(Uri imageUrl) {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(imageUrl, "image/*");
cropIntent.putExtra("cropWidth", "true");
cropIntent.putExtra("outputX", cropTargetWidth);
cropIntent.putExtra("outputY", cropTargetHeight);
File copyFile = FileHelper.createFileByType(mContext, destType, String.valueOf(System.currentTimeMillis()));
copyUrl = Uri.fromFile(copyFile);
cropIntent.putExtra("output", copyUrl);
startActivityForResult(cropIntent, REQUEST_CODE_CROP_PIC);
}