65.9K
CodeProject is changing. Read more.
Home

How to cut a bitmap?

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (2 votes)

Aug 23, 2013

CPOL

2 min read

viewsIcon

41413

downloadIcon

524

Cut bitmap!

Introduction

I have explained how to combine many bitmaps into one here. In this tip, I will guide the way to create a bitmap by cutting from a part of an original bitmap.

Using the code

At first, create an image original.png has size (400px, 400px) as below

Create bitmap from this image

Bitmap origialBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.original); 

Create empty bitmap

Bitmap cutBitmap = Bitmap.createBitmap(origialBitmap.getWidth() / 2, 
       origialBitmap.getHeight() / 2, Config.ARGB_8888);   

Normally, to cut an specified area of a bitmap, they use.

public void drawBitmap (Bitmap originalBitmap, Rect src, Rect dst, Paint paint)
  • src: The rectangle is used to specified the area will be cut in originalBitmap
  • dst: After basing on src rectangle to cut the from an area of originalBitmap, the result bitmap will be translated/scaled by dst rectangle. With my experience, the easiest way is: size of src = size of cutbitmap = size of dst. It will help to keep the ratio.

How to cut left|top?

Based on the explanation above, if we want to cut left|top to get image ①, to create src rectangle, please see this picture:

To cut bitmap in red rectangle, we are easy to create src rectangle as below:

Rect srcRect = new Rect(0, 0, origialBitmap.getWidth() / 2, origialBitmap.getHeight() / 2); 

Using above src to cut bitmap, we will have:

About the dest rectangle, the easiest way is creating it with the same size with cutBitmap size

Rect srcRect = new Rect(0, 0, origialBitmap.getWidth() / 2, origialBitmap.getHeight() / 2); 

Draw bitmap!

canvas.drawBitmap(origialBitmap, srcRect, desRect, null);  

Please view the result in device

After cutting the left|top, it is easy to cut

right|top

private Bitmap cutRightTop() {
    Bitmap origialBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.original);
    Bitmap cutBitmap = Bitmap.createBitmap(origialBitmap.getWidth() / 2,
            origialBitmap.getHeight() / 2, Config.ARGB_8888);
    Canvas canvas = new Canvas(cutBitmap);
    Rect desRect = new Rect(0, 0, origialBitmap.getWidth() / 2, origialBitmap.getHeight() / 2);
    Rect srcRect = new Rect(origialBitmap.getWidth() / 2, 0, origialBitmap.getWidth(),
            origialBitmap.getHeight() / 2);
    canvas.drawBitmap(origialBitmap, srcRect, desRect, null);
    return cutBitmap; 
}

left|bottom

private Bitmap cutLeftBottom() {
    Bitmap origialBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.original);
    Bitmap cutBitmap = Bitmap.createBitmap(origialBitmap.getWidth() / 2,
            origialBitmap.getHeight() / 2, Config.ARGB_8888);
    Canvas canvas = new Canvas(cutBitmap);
    Rect srcRect = new Rect(0, origialBitmap.getHeight() / 2, origialBitmap.getWidth() / 2,
            origialBitmap.getHeight());
    Rect desRect = new Rect(0, 0, origialBitmap.getWidth() / 2, origialBitmap.getHeight() / 2);
    canvas.drawBitmap(origialBitmap, srcRect, desRect, null);
    return cutBitmap;
} 

right|bottom

private Bitmap cutRightBottom() {
    Bitmap origialBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.original);
    Bitmap cutBitmap = Bitmap.createBitmap(origialBitmap.getWidth() / 2,
            origialBitmap.getHeight() / 2, Config.ARGB_8888);
    Canvas canvas = new Canvas(cutBitmap);
    Rect desRect = new Rect(0, 0, origialBitmap.getWidth() / 2, origialBitmap.getHeight() / 2);
    Rect srcRect = new Rect(origialBitmap.getWidth() / 2, origialBitmap.getHeight() / 2,
            origialBitmap.getWidth(),
            origialBitmap.getHeight());
    canvas.drawBitmap(origialBitmap, srcRect, desRect, null);
    return cutBitmap;
} 

Points of Interest

Scale ratio 

If you want to create bitmap with both number 1 and 2 in result, at first, src rectangle will be:

Rect srcRect = new Rect(0, 0, origialBitmap.getWidth(), origialBitmap.getHeight() / 2); 

But if we keep cut bitmap size and dest as old source code, what will happen? It is the result:

We can see the bitmap result has not good scaling. How to fix? Please make the size of cut bitmap and dest rectangle is the same with srcRect.

Bitmap cutBitmap = Bitmap.createBitmap(origialBitmap.getWidth(),
        origialBitmap.getHeight() / 2, Config.ARGB_8888);
Rect desRect = new Rect(0, 0, origialBitmap.getWidth(),
        origialBitmap.getHeight() / 2);

The result will be: 

 

But in fact, sometime, user wants to create cutBitmap smaller (or bigger than the size of srcRect). Suppose that scale to 0.5. Please note that: 

dest = 0.5 * src

Rect desRect = new Rect(0, 0, (int) (origialBitmap.getWidth() * 0.5), (int) (origialBitmap.getHeight() / 2 * 0.5)); 

After that,  the cutBitmap size will base on desRect is the best way.

Bitmap cutBitmap = Bitmap.createBitmap(desRect.width(), desRect.height(), Config.ARGB_8888); 

The result of scaling 0.5 will be:

 

Summary 

To cut bitmap, please:

  • Specified the cutting area, then making the src rectangle firstly. 
  • What scale ratio user wants? Base on it to create dest = ratio * src .
  • Specified the cuttingBitmap size base on dest rectangle is the best way.