Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Resizing Bitmaps without losing quality

i've really searched through over the entire web before posting. My problem is that i cannot resize bitmap without losing the quality of the image (the quality is really bad and pixelated).

I take the bitmap from camera and then i have to downscale it, so i can upload it to the server much faster.

This is the function that does the sampling

public Bitmap resizeBitmap(Bitmap bitmap){
         Canvas canvas = new Canvas();
         Bitmap resizedBitmap = null;
         if (bitmap !=null) {
                int h = bitmap.getHeight();
                int w = bitmap.getWidth();
                int newWidth=0;
                int newHeight=0;

                if(h>w){
                    newWidth = 600;
                    newHeight = 800;
                }

                if(w>h){
                    newWidth = 800;
                    newHeight = 600;
                    }

                float scaleWidth = ((float) newWidth) / w;
                float scaleHeight = ((float) newHeight) / h;



                Matrix matrix = new Matrix();
                // resize the bit map
                matrix.preScale(scaleWidth, scaleHeight);

                resizedBitmap  = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);



                Paint paint = new Paint();
                paint.setAntiAlias(true);
                paint.setFilterBitmap(true);
                paint.setDither(true);

                canvas.drawBitmap(resizedBitmap, matrix, paint);



            }


        return resizedBitmap;   

and this is how i get the image from activity result

 protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         if(resultCode != RESULT_CANCELED){

         if (requestCode == 0) {
             if (resultCode == RESULT_OK) {


                    getContentResolver().notifyChange(mImageUri, null);
                    ContentResolver cr = this.getContentResolver();

                    try
                    {
                        b = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri);
                        Log.d("foto", Integer.toString(b.getWidth()));
                        Log.d("foto", Integer.toString(b.getHeight()));
                        addPhoto.setImageBitmap(b);

                    }
                    catch (Exception e)
                    {
                        Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
                        Log.d("TAG", "Failed to load", e);
                    }



             }
         }

I'm starting to think that the best way to get a small picture size is to set the camera resolution. Anyone else can help?

like image 611
Vahn84 Avatar asked May 09 '13 15:05

Vahn84


People also ask

Can a bitmap image be scaled without losing image quality?

Note that the quality can be lost when resizing or re-formatting bitmap files such as GIF, JPEG, and even some PNGs. However, vector graphics will not suffer a quality loss even after resizing. Vector graphics can be sized up or down without sacrificing quality.

How do I increase the quality of a bitmap image?

Use lossless compression for the bitmap. In the Library window, right-click (Windows) or control-click (Macintosh) on the bitmap and select Properties. Choose Lossless from the Compression pop-up menu and click OK.

What happens to image quality when bitmaps are scaled?

Bitmap images are organised as a grid of coloured squares called pixels (short for 'picture elements'). When zooming in or enlarging a bitmap image, the pixels are stretched and made into larger blocks. This is why bitmap images appear as poor quality when enlarged too much.


2 Answers

Good downscaling algorithm (not nearest neighbor like) consists of just 2 steps (plus calculation of the exact Rect for input/output images crop):

  1. downscale using BitmapFactory.Options::inSampleSize->BitmapFactory.decodeResource() as close as possible to the resolution that you need but not less than it
  2. get to the exact resolution by downscaling a little bit using Canvas::drawBitmap()

Here is detailed explanation how SonyMobile resolved this task: http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application/

Here is the source code of SonyMobile scale utils: http://developer.sonymobile.com/downloads/code-example-module/image-scaling-code-example-for-android/

like image 148
goRGon Avatar answered Nov 07 '22 09:11

goRGon


Try below mentioned code for resizing bitmap.

 public Bitmap get_Resized_Bitmap(Bitmap bmp, int newHeight, int newWidth) {
        int width = bmp.getWidth();
        int height = bmp.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // CREATE A MATRIX FOR THE MANIPULATION
        Matrix matrix = new Matrix();
        // RESIZE THE BIT MAP
        matrix.postScale(scaleWidth, scaleHeight);

        // "RECREATE" THE NEW BITMAP
        Bitmap newBitmap = Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, false);
        return newBitmap ;
    }

I used this code to downsize my bitmap, and its quality, well.. , was acceptable.

Hope this helps.

like image 31
CRUSADER Avatar answered Nov 07 '22 09:11

CRUSADER