Android.graphics.Bitmap
lastmod 2018-08-17created 2014-02-138 edits
About Android bitmaps.
Bitmap decoding, prone to memory overflows and leaks
Even if you have read an image over the network successfully, there are many pitfalls when handling memory.
When a bitmap is large, take care not to trigger an Out of Memory error. An image file must be decoded before it is displayed on screen. The amount of memory a bitmap occupies is proportional to the size of the image. An image taken on a Galaxy Nexus is 2592x1936 pixels, which is about 19MB as a bitmap (2592 x 1936 x 4 bytes).[1] Loading this bitmap into memory on a device with 16MB of available memory causes an Out of Memory error. So it must be converted to a smaller size or decoded at lower quality. Android provides such features through the android.graphics.BitmapFactory.Options class.
| Android Bitmap Warning |
| Depending on the Android version, bitmap resources must be released explicitly. Android 3.1 (HONEYCOMB_MR1) and later store bitmaps in the VM heap memory, but Android 2.3 (Gingerbread) and earlier store bitmaps in the native heap. In the older versions, bitmaps are not subject to CG (garbage collection), so you must free the memory yourself by calling the recycle() method of the Bitmap object. Alternatively, set the inPurgeable flag of BitmapFactory.Options to true. |
Rounded corner bitmaps on Android
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = 12;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
Masking(crop) image
Finally got the solution while changing mask image and using of Xfermode with Bitmap
ImageView mImageView= (ImageView)findViewById(R.id.imageview_id);
Bitmap original = BitmapFactory.decodeResource(getResources(),R.drawable.content_image);
Bitmap mask = BitmapFactory.decodeResource(getResources(),R.drawable.mask);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(original, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
mImageView.setImageBitmap(result);
mImageView.setScaleType(ScaleType.CENTER);
mImageView.setBackgroundResource(R.drawable.background_frame);
Merging two bitmap images
/** 두 비트맵을 머지 한다.
* @param src 원래의 비트맵
* @param mergeBitmap 머지할 비트맵
* @return 병합한 비트맵
*/
public static Bitmap mergeBitmap(Bitmap src, Bitmap mergeBitmap) {
int width = src.getWidth();
int height = src.getHeight();
Bitmap mergeBitmap2 = Bitmap.createScaledBitmap(mergeBitmap, width, height, true);
for (int x=0; x<width; x++) {
for (int y=0; y<height; y++) {
int maskPixel = mergeBitmap2.getPixel(x, y);
int tilePixel = src.getPixel(x, y);
int mergedPixel = Color.argb(255, Color.red(tilePixel) | Color.red(maskPixel),
Color.green(tilePixel) | Color.green(maskPixel), Color.blue(tilePixel) | Color.blue(maskPixel));
src.setPixel(x, y, mergedPixel);
}
}
return src;
}
Converting a Drawable to a Bitmap
BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(R.drawable.icon);
Bitmap bitmap = drawable.getBitmap();
Compositing two bitmap images
private Bitmap mergeBitmap(Bitmap src1, Bitmap src2, int distanceLeft, int distanceTop) {
Bitmap overlay = Bitmap.createBitmap(src1.getWidth() + distanceLeft, src1.getHeight() + distanceTop, src1.getConfig());
Canvas canvas = new Canvas(overlay);
canvas.drawBitmap(src1, distanceLeft, distanceTop, null);
canvas.drawBitmap(src2, 0, 0, null);
return overlay;
}
Saving a bitmap image
First, set the permission as follows.
The source code is as follows.
imgview = (ImageView)findViewById(R.id.imageView1);
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.comp1_16);
imgview.setImageBitmap(bm);
try {
File file = new File("test.png");
FileOutputStream fos = new FileOutputStream(file);
bm.compress(CompressFormat.PNG, 100 , fos);
fos.flush();
fos.close();
Toast.makeText(this, "file ok", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "file error", Toast.LENGTH_SHORT).show();
}
Loading a saved Bitmap
When saving, a file name alone is enough and it is saved to the App's Data folder automatically, but when loading you must write out the full path.
try {
imgview = (ImageView)findViewById(R.id.imageView1);
String imgpath = "data/data/com.test.SDCard_Ani/files/test.png";
Bitmap bm = BitmapFactory.decodeFile(imgpath);
imgview.setImageBitmap(bm);
Toast.makeText(getApplicationContext(), "load ok", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "load error", Toast.LENGTH_SHORT).show();
}
Rotating a bitmap
Sample code that can rotate a Bitmap or Drawable is as follows.
public static Bitmap rotate(Bitmap b, int degrees) {
if ( degrees != 0 && b != null ) {
Matrix m = new Matrix();
m.setRotate( degrees, (float) b.getWidth() / 2, (float) b.getHeight() / 2 );
try {
Bitmap b2 = Bitmap.createBitmap( b, 0, 0, b.getWidth(), b.getHeight(), m, true );
if (b != b2) {
b.recycle();
b = b2;
}
} catch (OutOfMemoryError ex) {
// We have no memory to rotate. Return the original bitmap.
}
}
return b;
}
Resizing a bitmap
How to resize a bitmap on Android is as follows.
BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(R.drawable.movie_opening_1);
Bitmap movie_opening_bitmap = Bitmap.createScaledBitmap(drawable.getBitmap(), destWidth, destHeight, true);
See also
Favorite site
- Developer Android: Displaying Bitmaps Efficiently
- Android Developer: Bitmap reference
- [Recommended] Android app memory optimization 1
- How to join two bitmaps vertically
- How to composite two bitmap images
- Android YUV image processing
- YUV -> JPEG conversion
- Stackoverflow: Android Convert bitmap array to YUV (YCbCr NV21)
References
-
Hello_world_»_Android_App_memory_optimization.pdf ↩