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
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
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
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);
@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
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.
You can load the scaled version of bitmap with out fully loading the bitmap using following algorithm
Check the following post Android: Resize a large bitmap file to scaled output file for further details.