15

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

5 Answers 5

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

Sign up to request clarification or add additional context in comments.

2 Comments

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.
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!
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);

1 Comment

oops..sorry.. one more thing this method is intented for sdk version 2.3 or above...
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

1 Comment

What if startingSize > 32 initially because the input image is so big?
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.

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.