2013-05-09 61 views
4

我在发布前真的在整个网上搜索过。我的问题是,我无法调整位图的大小而不会丢失图像的质量(质量非常差和像素化)。Android:在不丢失质量的情况下调整位图大小

我从相机取得位图,然后我必须缩小它的大小,这样我就可以更快地将它上传到服务器。

这是做采样

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



      } 
     } 

我开始认为最好的方式来获得小图片尺寸是设置相机分辨率。任何人都可以帮忙吗?

回答

1

尝试Bitmap.createScaledBitmap。 它也有一个选项来过滤源。

+2

谢谢...但我已经试过: resizedBitmap = Bitmap.createScaledBitmap(bitmap,newWidth,newHeight,true); 但它是一样的...仍然块状和像素化 – Vahn84 2013-05-09 15:51:23

+0

我明白了。我记住的最后一个提示是你检查BitmapFactory.Options类,初始化和解码你的位图时使用质量相关的选项。这里的API链接:http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html – Mena 2013-05-09 17:47:31

+0

我已经达到了至少可以接受的解决从位图uri bitmap.factory选项的位图。但它仍然不是我想的质量。 Facebook和G +如何处理照片上传?我看到他们调整了您上传的所有图片。他们如何做到这一点,而不会丢失一个质量像素? – Vahn84 2013-05-10 07:23:23

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

我用这个代码来缩小我的位图,它的质量,以及.. ..是可以接受的。

希望这会有所帮助。

+1

不,尝试,但它是相同的结果像以前一样 – Vahn84 2013-05-09 16:03:13

+0

没有改进过的位图的品质,得到相同的结果,以前 – sumeet 2018-01-03 06:53:42

6

良好缩小算法(如不近邻)由仅2步骤(加上用于输入/输出图像作物确切矩形的计算):

  1. 缩减使用BitmapFactory.Options :: inSampleSize- > BitmapFactory.decodeResource()尽可能接近到你所需要的分辨率,但不低于其
  2. 得到精确的分辨率,通过缩减使用帆布:: drawBitmap()一点点

下面是详细的解释SonyMobile如何解决这个任务:http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application/

这里是SonyMobile规模utils的源代码:http://developer.sonymobile.com/downloads/code-example-module/image-scaling-code-example-for-android/

+2

这应该是公认的答案。刚刚实现了链接文章中描述的内容,结果明显好于使用简单的createScaledBitmap,并且在缩小时使用得更少。 结果仍然不如降尺度时的好,例如,在Photoshop中。 – 2015-04-30 16:06:23

+0

我已经尝试了FIT方法,它与使用默认Bitmap.createScaledBitmap的质量完全相同。可能会更快/更少的内存消耗,但质量是相同的。 – lxknvlk 2017-01-04 22:36:35

+0

upd - 只是检查时间,两种方法使用相同的时间,在我的情况下,这些是2-3毫秒。我没有使用他们的解码方法,因为我有一个准备好的位图作为输入,所以也没有改变内存使用情况。 – lxknvlk 2017-01-04 22:48:02

相关问题