首页 > 解决方案 > android如何缩小位图并保持其纵横比

问题描述

使用返回位图的 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))

看到了安卓样本

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:240 x h:120)从 的 src 位图获得一个新的位图(w:300 x h:600),它将映射到(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-bitmapbitmapfactoryimage-scaling

解决方案


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

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)

第三是不保持长宽比,虽然有尺寸对。

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

在此处输入图像描述


推荐阅读