Take the 2-minute tour ×

I trying to achieve good quality image resize in Android. I'm trying all methods listed here on SO and that I could find on Google, but I still can't find a good solution.

To exemplify what I'm trying to achieve and what problems I'm having, I'm posting 3 images with the different results. Basically I'm just getting a big image from SD card, resizing and cropping it.

Here is the desired result, achieved on Photoshop: resize with photoshop

And this is when I use the tradicional method of drawing on canvas draw on canvas

And this result is when I use ImageMagick. It's better, but in some devices it takes minutes to resize (not cool for a mobile app) resize with imagemagick

So, here is my code using the canvas method:

BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(params[0].path_source, o);

BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inDither = false;
options.inPurgeable = true;
options.inScaled = false;
options.inPreferQualityOverSpeed = true;
options.inSampleSize = Utils.calculateInSampleSize(o, 640, 640);

Bitmap image = BitmapFactory.decodeFile(params[0].path_source, options);

... calculate right x, y for cropping ..

Matrix m = new Matrix();
m.postScale(new_width/(float)width, new_width/(float)width);

Bitmap result = Bitmap.createBitmap(640, 640, Config.ARGB_8888);
Canvas canvas = new Canvas(result);

Paint paint = new Paint();

canvas.drawBitmap(image, -x, -y, paint);

FileOutputStream fos = activity.openFileOutput(Utils.NOME_ARQUIVO_FOTO, Context.MODE_PRIVATE);
result.compress(CompressFormat.JPEG, 100, fos);

Now here is the code using ImageMagick:

ImageInfo info = new ImageInfo(params[0].path_source);
MagickImage image = new MagickImage(info);

//I can optionally use sampleImage for better performance, but worse quality (still better then android canvas)
//image = image.sampleImage(new_sampled_width, new_sampled_height);

image = image.scaleImage(new_width, new_height);
image = image.cropImage(new Rectangle(x, y, 640, 640));
image = image.rotateImage(rotation);

byte blob[] = image.imageToBlob(info);
FileOutputStream fos = activity.openFileOutput(Utils.NOME_ARQUIVO_FOTO, Context.MODE_PRIVATE);

Edit: I'm using Android 2.3.4 on a Xperia Play for testing

Edit 2: Saving with CompressFormat.PNG achieves near perfect result! Thanks FunkTheMonk for the tip! Only problem is that I use ImageMagick for blending this image with another later in the code, and I couldn't manage to build ImageMagick with PNG support

share|improve this question
You might wish to explain precisely what you do not like about your two candidate output images. –  CommonsWare May 15 '13 at 14:08
They look ok to me... is the performance you're worried about? –  FunkTheMonk May 15 '13 at 14:09
Look at the color banding in the white parts of the photo. Thanks! –  Paulo Cesar May 15 '13 at 14:09
About performance: using canvas is nearly instantaneous, but with ImageMagick it took 28 seconds to generate that image. It's just too slow –  Paulo Cesar May 15 '13 at 14:10
Sure the colour banding isn't a jpg artefact? –  FunkTheMonk May 15 '13 at 14:23
show 3 more comments

Your Answer



Browse other questions tagged or ask your own question.