Saturday, 14 July 2012

Scale bitmap Efficiently

Remark: I have a exercise "Display Gallery selected image using BitmapFactory" before. The original idea is to select image using Android build-in app Gallery, and display on a ImageView, FOR SMALL IMAGE. Recently found that it cannot display large image, such as original photos from camera ~ but I don't know why no error reported!!!

It may be due to the Bitmap is too large for the ImageView. To scale-down the bitmap before display, Android Developer Site have a good article to describe "Loading Large Bitmaps Efficiently".


The old exercise is modified with scale-down bitmap and re-posted here:

with scale-down bitmap


Main Code:
package com.example.androidselectimage;

import java.io.FileNotFoundException;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

TextView textTargetUri;
ImageView targetImage;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button buttonLoadImage = (Button)findViewById(R.id.loadimage);
textTargetUri = (TextView)findViewById(R.id.targeturi);
targetImage = (ImageView)findViewById(R.id.targetimage);

buttonLoadImage.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0);
}});

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == RESULT_OK){
Uri targetUri = data.getData();
textTargetUri.setText(targetUri.toString());

Toast.makeText(getApplicationContext(),
"ImageView: " + targetImage.getWidth() + " x " + targetImage.getHeight(),
Toast.LENGTH_LONG).show();

Bitmap bitmap;
bitmap = decodeSampledBitmapFromUri(
targetUri,
targetImage.getWidth(), targetImage.getHeight());

if(bitmap == null){
Toast.makeText(getApplicationContext(), "the image data could not be decoded", Toast.LENGTH_LONG).show();

}else{
Toast.makeText(getApplicationContext(),
"Decoded Bitmap: " + bitmap.getWidth() + " x " + bitmap.getHeight(),
Toast.LENGTH_LONG).show();
targetImage.setImageBitmap(bitmap);
}
}
}

/*
* How to "Loading Large Bitmaps Efficiently"?
* Refer: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
*/

public Bitmap decodeSampledBitmapFromUri(Uri uri, int reqWidth, int reqHeight) {

Bitmap bm = null;

try{
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);

// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}

return bm;
}

public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}

}


Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/loadimage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Load Image" />
<TextView
android:id="@+id/targeturi"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/targetimage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop" />
</LinearLayout>


Download the files.

Borneo08

About Borneo08

Author Description here.. Nulla sagittis convallis. Curabitur consequat. Quisque metus enim, venenatis fermentum, mollis in, porta et, nibh. Duis vulputate elit in elit. Mauris dictum libero id justo.

Subscribe to this Blog via Email :

More links

Related Posts Plugin for WordPress, Blogger...