【问题标题】:android how to scale down a bitmap and keep its aspect rationandroid如何缩小位图并保持其纵横比
【发布时间】:2021-11-23 12:31:38
【问题描述】:

使用返回位图的 3rd 方库。在应用程序中它想缩小位图。

static  public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;

        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);

        Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
                matrix, false);

        return resizedBitmap;
    }
===
Bitmap doScaleDownBitmap() {

        Bitmap bitmap = libGetBitmap();  // got the bitmap from the lib

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        if (width > 320 || height > 160) {
            bitmap = getResizedBitmap(bitmap, 320, 160);
        }

        System.out.println("+++ width;"+width+", height:"+height+ ", return bmp.w :"+bitmap.getWidth()+", bmp.h:"+bitmap.getHeight());

        return bitmap;
    }

测试位图 (348x96) 的日志:

+++ width;348, height:96, return bmp.w :320, bmp.h:160

看起来调整大小的位图没有正确缩放,不应该是320 x 88 来保持纵横比吗?

(从 (348x96) ==> (320x160) 开始)

看到android sample

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

如果已有位图,如何应用?

或者缩小位图的正确方法是什么?

编辑:

这可以保持纵横比,并且所需尺寸之一(宽度或高度)将用于生成的位图。基本上是CENTER_FIT

但是它不会生成具有所需宽度和高度的位图。

例如想要从(w:300 x h:600) 的src 位图获得(w:240 x h:120) 的新位图,它将映射到(w:60 x h:120)

如果希望新位图具有(w:240 x h:120),我想它需要在这个新位图之上进行额外操作。

有没有更简单的方法?

  public static Bitmap scaleBitmapAndKeepRation(Bitmap srcBmp, int dstWidth, int dstHeight) {
        Matrix matrix = new Matrix();
        matrix.setRectToRect(new RectF(0, 0, srcBmp.getWidth(), srcBmp.getHeight()), 
                new RectF(0, 0, dstWidth, dstHeight), 
                Matrix.ScaleToFit.CENTER);
        Bitmap scaledBitmap = Bitmap.createBitmap(srcBmp, 0, 0, srcBmp.getWidth(), srcBmp.getHeight(), matrix, true);
        return scaledBitmap;
    }

【问题讨论】:

    标签: android-bitmap bitmapfactory image-scaling


    【解决方案1】:

    当您按比例缩小位图时,如果宽度和高度不能被比例整除,您应该期望比例发生微小变化。如果您不希望这样,请先将图像裁剪为可分割然后缩放。

    float scale=0.5f;
    scaledBitmap=Bitmap.createScaledBitmap(bitmap,
        (int)(bitmap.width()*scale),
        (int)(bitmap.height()*scale),
        true); //bilinear filtering 
    

    【讨论】:

      【解决方案2】:

      找到了方法,我相信还有更好的方法

      public static Bitmap updated_scaleBitmapAndKeepRation(Bitmap srcBitmap, int targetBmpWidth,
                                                  int targetBmpHeight) {
      
              int width = srcBitmap.getWidth();
              int height = srcBitmap.getHeight();
              if (targetBmpHeight > 0 && targetBmpWidth > 0 && (width != targetBmpWidth || height != targetBmpHeight))  {
      
                  // create a canvas with the specified bitmap to draw into.
                  Bitmap scaledImage = Bitmap.createBitmap(targetBmpWidth, targetBmpHeight, Bitmap.Config.ARGB_4444);
                  Canvas canvas = new Canvas(scaledImage);
      
                  // draw transparent background color
                  Paint paint = new Paint();
                  paint.setColor(Color.TRANSPARENT);
                  paint.setStyle(Paint.Style.FILL);
                  canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);
      
                  // draw the source bitmap on canvas and scale the image with center_fit (the source image's larger side is mapped to the corresponding desired dimensions, and the other side scaled with aspect ration)
                  Matrix matrix = new Matrix();
                  matrix.setRectToRect(new RectF(0, 0, srcBitmap.getWidth(), srcBitmap.getHeight()),
                          new RectF(0, 0, targetBmpWidth, targetBmpHeight),
                          Matrix.ScaleToFit.CENTER);
                  canvas.drawBitmap(srcBitmap, matrix, null);
      
                  return scaledImage;
      
              } else {
                  return srcBitmap;
              }
          }
      

      结果截图:

      第一张图片是src(w:1680 x h:780)

      第二个来自问题部分中的scaleBitmapAndKeepRation(),它具有缩放图像但尺寸(w:60 x h:120)不是所需尺寸(w: 240 x h:120)

      第三个是不保持纵横比的,虽然有尺寸对。

      4th 来自updated_scaleBitmapAndKeepRation(),它具有所需的尺寸,图像为 center_fit 并保持纵横比。

      【讨论】:

        猜你喜欢
        • 2013-03-04
        • 2011-08-24
        • 1970-01-01
        • 2014-09-17
        • 2014-06-02
        • 1970-01-01
        • 2019-08-10
        • 2015-06-03
        • 2021-08-06
        相关资源
        最近更新 更多