16

I would like to load a cropped version of a bitmap image into a Bitmap object, without loading the original bitmap as well.

Is this at all possible without writing custom loading routines to handle the raw data?

Thanks, Sandor

Schermvlieger
  • 206
  • 2
  • 4

5 Answers5

13

It's actually very straightforward to do. Use

Bitmap yourBitmap = Bitmap.createBitmap(sourceBitmap, x to start from, y to start from, width, height)

Update: use BitmapRegionDecoder

Steve Haley
  • 55,374
  • 17
  • 77
  • 85
  • 4
    Thanks Steve, but that would require me to load in the sourceBitmap first, and I am trying to avoid doing that, since it is too large to fit in memory, and I want to work with a bitmap that has not been downsampled. – Schermvlieger Apr 09 '10 at 10:49
  • Oops, you're right, I didn't read that part of your question properly. I'm not sure then how to do this without downsampling. In fact a very similar problem is on my own figure-out-how-to-do list as well! – Steve Haley Apr 09 '10 at 11:10
10

try this

InputStream istream =   null;
try {
     istream = this.getContentResolver().openInputStream(yourBitmapUri);
} catch (FileNotFoundException e1) {
     e1.printStackTrace();
}

BitmapRegionDecoder decoder     =   null;
try {
    decoder = BitmapRegionDecoder.newInstance(istream, false);
} catch (IOException e) {
    e.printStackTrace();
}
Bitmap bMap = decoder.decodeRegion(new Rect(istream, x to start from, y to start from, x to end with, y to end with), null);    
imageView.setImageBitmap(bMap);
Renjith
  • 5,783
  • 9
  • 31
  • 42
0

@RKN

Your method can also throw OutOfMemoryError exception - if cropped bitmap exceeds VM.

My method combines Yours and protection against this exeption: (l, t, r, b - % of image)

    Bitmap cropBitmap(ContentResolver cr, String file, float l, float t, float r, float b)
{
    try 
    {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;

        // First decode with inJustDecodeBounds=true to check dimensions
        BitmapFactory.decodeFile(file, options);
        int oWidth = options.outWidth;
        int oHeight = options.outHeight;

        InputStream istream = cr.openInputStream(Uri.fromFile(new File(file)));

        BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(istream, false);
        if (decoder != null)
        {
            options = new BitmapFactory.Options();

            int startingSize = 1;
            if ((r - l) * oWidth * (b - t) * oHeight > 2073600)
                startingSize = (int) ((r - l) * oWidth * (b - t) * oHeight / 2073600) + 1;

            for (options.inSampleSize = startingSize; options.inSampleSize <= 32; options.inSampleSize++)
            {
                try
                {
                    return decoder.decodeRegion(new Rect((int) (l * oWidth), (int) (t * oHeight), (int) (r * oWidth), (int) (b * oHeight)), options);    
                }
                catch (OutOfMemoryError e)
                {
                    Continue with for loop if OutOfMemoryError occurs
                }
            }
        }
        else
            return null;
    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }
    catch (IOException e) 
    {
        e.printStackTrace();
    }

    return null;
}

and returns max available bitmap or null

Mrooc
  • 9
  • 3
0

Use RapidDecoder.

And simply do this

import rapid.decoder.BitmapDecoder;

Rect bounds = new Rect(left, top, right, bottom);
Bitmap bitmap = BitmapDecoder.from(getResources(), R.drawable.image)
        .region(bounds).decode();

It requires Android 2.2 or above.

suckgamony
  • 804
  • 7
  • 5
0

You can load the scaled version of bitmap with out fully loading the bitmap using following algorithm

  • Calculate the maximum possible inSampleSize that still yields an image larger than your target.
  • Load the image using BitmapFactory.decodeFile(file, options), passing inSampleSize as an option.
  • Resize to the desired dimensions using Bitmap.createScaledBitmap().

Check the following post Android: Resize a large bitmap file to scaled output file for further details.

Community
  • 1
  • 1
Zain Ali
  • 15,535
  • 14
  • 95
  • 108