How to work with Bitmap in Android

How to work with Bitmap in Android

A bitmap (or raster graphic) is a digital image composed of a matrix of dots. When viewed at 100%, each dot corresponds to an individual pixel on a display. In a standard bitmap image, each dot can be assigned a different color.

In this instance we will simply create a Bitmap directly:

Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);

A bitmap is simply a rectangle of pixels. Each pixel can be set to a given color but exactly what color depends on the type of the pixel. The first two parameters give the width and the height in pixels. The third parameter specifies the type of pixel you want to use. This is where things can get complicated. The specification ARGB_8888 means create a pixel with four channels ARGB - Alpha, Red, Green, Blue and allocate each 8 bits of storage. As four eights are 32 this is 32 bit graphics. The alpha channel lets you set an opacity.

You can get Bitmap from Drawables via following code.

ImageView image = (ImageView) findViewById(R.id.image);
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.car);
image.setImageBitmap(b);

To convert a Bitmap object into a Drawable you can use the following code.

Drawable d = new BitmapDrawable(getResources(), bitmap);

Scaling a Bitmap

If we need to resize a Bitmap, we can call the createScaledBitmap method to resize any bitmap to our desired width and height:

// load a bitmap from the drawable folder
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.car);

// resize the bitmap to 150x100 (width x height)
Bitmap scaled = Bitmap.createScaledBitmap(b, 150, 100, true);

// loads the resized Bitmap into an ImageView
ImageView image = (ImageView) findViewById(R.id.image);
image.setImageBitmap(scaled);

You often want to resize a bitmap but preserve the aspect ratio using a BitmapScaler utility class with code like this:

public class BitmapScaler{
    // Scale and maintain aspect ratio given a desired width
    // BitmapScaler.scaleToFitWidth(bitmap, 100);
    public static Bitmap scaleToFitWidth(Bitmap b, int width) {
        float factor = width / (float) b.getWidth();
        return Bitmap.createScaledBitmap(b, width, (int) (b.getHeight() * factor), true);
    }

    // Scale and maintain aspect ratio given a desired height
    // BitmapScaler.scaleToFitHeight(bitmap, 100);
    public static Bitmap scaleToFitHeight(Bitmap b, int height) {
        float factor = height / (float) b.getHeight();
        return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factor), height, true);
    }

    // ...
}

Combine multiple bitmaps to a single bitmap

Bitmap image1 = BitmapFactory.decodeResource(getResources(), R.drawable.image1);
Bitmap image2 = BitmapFactory.decodeResource(getResources(), R.drawable.image2);

Bitmap merged = Bitmap.createBitmap(image1.getWidth(), image1.getHeight(), image1.getConfig());
Canvas canvas = new Canvas(merged);
canvas.drawBitmap(image1, 0f, 0f, null);
canvas.drawBitmap(image2, 10, 10, null);

imageView.setImageBitmap(merged);

Rounded corners

In Android, you can create bitmaps with anti-aliased rounded corners on the fly using the code snippet below.

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;
}

Converting a File object to Bitmap

Bitmap bitmap = BitmapFactory.decodeFile(fileObj.getPath());
imageView.setImageBitmap(bitmap);

Save Bitmap to file

Bitmap bitmap = Bitmap.createScaledBitmap(b, 150, 150, false);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();

bitmap.compress(Bitmap.CompressFormat.JPEG, 70, outStream);
//bitmap.compress(CompressFormat.PNG, 0, outStream);

File f = new File(Environment.getExternalStorageDirectory() + File.separator + "filename.jpg");
f.createNewFile();

try {
    FileOutputStream fo = new FileOutputStream(f);
    fo.write(outStream.toByteArray());

    fo.flush();
    fo.close();
} catch (FileNotFoundException e) {
    Log.w("TAG", "Error saving image file: " + e.getMessage());
    return false;
} catch (IOException e) {
    Log.w("TAG", "Error saving image file: " + e.getMessage());
    return false;
}

Send Bitmap using Intent

In your calling activity.

Intent i = new Intent(this, NextActivity.class);
Bitmap b; // your bitmap
ByteArrayOutputStream bs = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 50, bs);
i.putExtra("byteArray", bs.toByteArray());
startActivity(i);

In your receiving activity

if (getIntent().hasExtra("byteArray")) {
    ImageView preview = new ImageView(this);
    byte[] byteArray = getIntent().getByteArrayExtra("byteArray");
    Bitmap b = BitmapFactory.decodeByteArray(byteArray,0,byteArray.length);
    preview.setImageBitmap(b);
}

Download Bitmap from URL

public Bitmap getBitmapFromURL(String strURL) {
    try {
        URL url = new URL(strURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(input);
        return myBitmap;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}
comments powered by Disqus