In this article, two approach are provided to resize bitmap:
- Bitmap.createScaledBitmap
- BitmapFactory.Options.inSampleSize
But...which one is better? In the code, the process time are also provided for reference.
In order to count the process time, the code are run on UI Thread and the process time are calculated base on the start time and end time of the process. Please note that in normal case, you should not place such a long running process in UI Thread.
Place a test file in "/sdcard/tmp/testphoto.jpg".
Main Code, MainActivity.java.
package com.example.androidresizebitmap;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
Button btnProcessA, btnProcessB;
ImageView processedImgA, processedImgB;
TextView statusA, statusB;
/*
* Normally do not hardcode "/sdcard/";
* use Environment.getExternalStorageDirectory().getPath() instead
*/
static String imgSouce = "/sdcard/tmp/testphoto.jpg";
static int w = 250;
static int h = 250;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnProcessA = (Button)findViewById(R.id.processbtna);
btnProcessB = (Button)findViewById(R.id.processbtnb);
processedImgA = (ImageView)findViewById(R.id.processedimg_a);
processedImgB = (ImageView)findViewById(R.id.processedimg_b);
statusA = (TextView)findViewById(R.id.statusa);
statusB = (TextView)findViewById(R.id.statusb);
btnProcessA.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
resizeA();
}});
btnProcessB.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
resizeB();
}});
}
private void resizeA(){
Long startTime = System.currentTimeMillis();
Bitmap bitmap_Source = BitmapFactory.decodeFile(imgSouce);
float factorH = h / (float)bitmap_Source.getHeight();
float factorW = w / (float)bitmap_Source.getWidth();
float factorToUse = (factorH > factorW) ? factorW : factorH;
Bitmap bm = Bitmap.createScaledBitmap(bitmap_Source,
(int) (bitmap_Source.getWidth() * factorToUse),
(int) (bitmap_Source.getHeight() * factorToUse),
false);
Long endTime = System.currentTimeMillis();
Long processTime = endTime - startTime;
statusA.setText("Process Time (MilliSeconds): " + String.valueOf(processTime));
processedImgA.setImageBitmap(bm);
}
private void resizeB(){
Long startTime = System.currentTimeMillis();
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bm = BitmapFactory.decodeFile(imgSouce, bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)h);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)w);
if (heightRatio > 1 || widthRatio > 1)
{
if (heightRatio > widthRatio){
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
bmpFactoryOptions.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(imgSouce, bmpFactoryOptions);
Long endTime = System.currentTimeMillis();
Long processTime = endTime - startTime;
statusB.setText("Process Time (MilliSeconds): " + String.valueOf(processTime));
processedImgB.setImageBitmap(bm);
}
}
Layout, activity_main.xml.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/padding_medium"
android:text="@string/hello_world"
tools:context=".MainActivity" />
<Button
android:id="@+id/processbtna"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Resize using process A"/>
<ImageView
android:id="@+id/processedimg_a"
android:layout_width="250px"
android:layout_height="250px"/>
<TextView
android:id="@+id/statusa"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/processbtnb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Resize using process B"/>
<ImageView
android:id="@+id/processedimg_b"
android:layout_width="250px"
android:layout_height="250px"/>
<TextView
android:id="@+id/statusb"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
-
More about Image processing on Android.