Android:改变位图大小而不失去质量

8

在发布之前,我真正地搜索了整个网页。我的问题是,我无法调整位图大小而不失去图像的质量(质量非常差且呈现像素化效果)。

我从相机中获取位图,然后必须将其缩小,以便更快地将其上传到服务器。

这是执行采样的函数

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;   

以下是我从活动结果中获取图像的方法:

 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);
                    }



             }
         }

我开始认为获得小图片尺寸的最佳方法是设置相机分辨率。还有其他人能帮忙吗?

4个回答

10

2
这应该是被接受的答案。只需实现链接文章中描述的内容,结果比仅使用createScaledBitmap显着更好,并且在缩小时使用的资源也少得多。然而,结果仍不如在Photoshop中缩小的效果好。 - Martin Konicek
我已经尝试过FIT方法,它的质量与使用默认的Bitmap.createScaledBitmap完全相同。可能更快/消耗更少的内存,但质量是一样的。 - lxknvlk
更新 - 刚刚检查了时间,两种方法使用的时间相同,在我的情况下是2-3毫秒。我没有使用它们的解码方法,因为我有一个准备好的位图作为输入,所以内存使用也没有变化。 - lxknvlk
不幸的是,在我的情况下,这两个链接都不再起作用了。每个链接都会重定向到https://developer.sony.com/。 - kkaun
4
https://web.archive.org/web/20171011183652/http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application/ - anemomylos

2
尝试以下代码来调整位图大小。
 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 ;
    }

我使用了这段代码来缩小位图,质量还不错。希望这能帮到您。

没有Bitmap质量的改进,得到了与以前相同的结果。 - sumeet

1

4
谢谢,但我已经尝试过了:resizedBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);但效果相同...仍然模糊并且有像素块。 - Vahn84
我明白了。我心中最后一个提示是,您可以检查BitmapFactory.Options类,在解码位图时初始化和使用与质量相关的选项。这是API链接:http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html - Mena
我通过使用Bitmap.Factory选项从URI解码位图,已经得到了至少可以接受的结果。但它仍然不是我想要的质量。Facebook和G+如何处理照片上传?我看到他们会调整你上传的所有图像的大小。他们如何在不失去任何像素质量的情况下进行调整? - Vahn84
我建议你更深入地了解BitmapFactory.Options - 以防你错过了什么。我知道这不是一个非常有用的答案,但我不知道如何帮助你更多 :( - Mena
@Vahn84,你能更新一下你最终选择了什么吗? - turbo2oh

0

我所遇到的最佳缩放方法 该方法使用createScaledBitmap,其中高度和宽度是基于位图的高度和宽度以及比例计算的,因此不会失去质量

 public Bitmap resize(Bitmap imaged, int maxWidth, int maxHeight) {
        Bitmap image = imaged;

        if (maxHeight > 0 && maxWidth > 0) {
            int width = image.getWidth();
            int height = image.getHeight();
            float ratioBitmap = (float) width / (float) height;
            float ratioMax = (float) maxWidth / (float) maxHeight;
            int finalWidth = maxWidth;
            int finalHeight = maxHeight;
            if (ratioMax > 1) {
                finalWidth = Math.round(((float) maxHeight * ratioBitmap));
            } else {
                finalHeight = Math.round(((float) maxWidth / ratioBitmap));
            }
            return image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, false);
        }
        return image;
    }

使用方法:

Bitmap resizedBitmap = resize(scrBitMap,640,640);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接