Bitmap使用容易被忽略的一个小问题点

时间:2021-04-17 15:41:52
下面的代码是存在问题的:

Matrix matrix = new Matrix();
matrix.setRotate(0.013558723994643297f);
Log.d(TAG,"isIdentity = " + matrix.isIdentity());
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Log.d(TAG, "bitmap = " + bitmap.isMutable());
Bitmap targetBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());//或者Bitmap targetBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),matrix,true);
Log.d(TAG, "bitmap = " + bitmap + ",targetBmp = " + targetBmp);
if (!bitmap.isRecycled()) {
bitmap.recycle();
}

打印的结果是bitmap和targetBmp是同一个对象。 isMutable = false,isIdentity = true。
如果把targetBmp返回出去,就会导致使用者报错。

也就是说Bitmap.createBitmap可能返回同一个对象。

在看源码,确实有这么一段代码:
// check if we can just return our argument unchanged
if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&
height == source.getHeight() && (m == null || m.isIdentity())) {
return source;
}

所以,要注意Bitmap.createBitmap的使用。

注:
在gallery2中,有这样的一段代码:
public static Bitmap resizeBitmapByScale(
Bitmap bitmap, float scale, boolean recycle) {
int width = Math.round(bitmap.getWidth() * scale);
int height = Math.round(bitmap.getHeight() * scale);
if (width == bitmap.getWidth()
&& height == bitmap.getHeight()) return bitmap;
Bitmap target = Bitmap.createBitmap(width, height, getConfig(bitmap));
Canvas canvas = new Canvas(target);
canvas.scale(scale, scale);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
canvas.drawBitmap(bitmap, 0, 0, paint);
if (recycle) bitmap.recycle();
return target;
}
这段代码不仅仅在gallery2中见过,很多时候,在其他的项目也见过使用这样的写法,所以,告诫自己以后要注意。