【问题标题】:Scaling bitmap to 80 percent将位图缩放到 80%
【发布时间】:2013-04-29 18:55:00
【问题描述】:

我正在尝试使用 options.inSampleSize 缩放位图,但据我了解,映射是这样的

  • 如果 inSampleSize 1 则结果图像为 100%

  • 如果inSampleSize 2 则结果图像为50%

  • 如果inSampleSize 3 则结果图像为33%

  • 如果inSampleSize 4 则结果图像为25%

  • 如果inSampleSize 5 则结果图像为20%

但我想要的是80% 可缩放的结果图像。我怎么得到它?

【问题讨论】:

    标签: android image android-layout bitmap drawable


    【解决方案1】:

    您可以使用此类中的calculateSampleSize 函数。它纯粹基于计算。

    package com.abhan.example.util;
    
    import android.content.res.Resources;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.Config;
    import android.graphics.BitmapFactory;
    import android.graphics.BitmapFactory.Options;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Rect;
    
    public class ScalingUtilities {
    
        public static Bitmap decodeResource(Resources res, int resId, int dstWidth,
                int dstHeight, ScalingLogic scalingLogic) {
            Options options = new Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeResource(res, resId, options);
            options.inJustDecodeBounds = false;
            options.inSampleSize = calculateSampleSize(options.outWidth,
                    options.outHeight, dstWidth, dstHeight, scalingLogic);
            Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId,
                    options);
    
            return unscaledBitmap;
        }
    
        public static Bitmap createScaledBitmap(Bitmap unscaledBitmap,
                int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
            Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(),
                    unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic);
            Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(),
                    unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic);
            Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(),
                    dstRect.height(), Config.ARGB_8888);
            Canvas canvas = new Canvas(scaledBitmap);
            canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(
                    Paint.FILTER_BITMAP_FLAG));
    
            return scaledBitmap;
        }
    
        public static enum ScalingLogic {
            CROP, FIT
        }
    
        public static int calculateSampleSize(int srcWidth, int srcHeight,
                int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
            if (scalingLogic == ScalingLogic.FIT) {
                final float srcAspect = (float) srcWidth / (float) srcHeight;
                final float dstAspect = (float) dstWidth / (float) dstHeight;
    
                if (srcAspect > dstAspect) {
                    return srcWidth / dstWidth;
                } else {
                    return srcHeight / dstHeight;
                }
            } else {
                final float srcAspect = (float) srcWidth / (float) srcHeight;
                final float dstAspect = (float) dstWidth / (float) dstHeight;
    
                if (srcAspect > dstAspect) {
                    return srcHeight / dstHeight;
                } else {
                    return srcWidth / dstWidth;
                }
            }
        }
    
        public static Rect calculateSrcRect(int srcWidth, int srcHeight,
                int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
            if (scalingLogic == ScalingLogic.CROP) {
                final float srcAspect = (float) srcWidth / (float) srcHeight;
                final float dstAspect = (float) dstWidth / (float) dstHeight;
    
                if (srcAspect > dstAspect) {
                    final int srcRectWidth = (int) (srcHeight * dstAspect);
                    final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
                    return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth,
                            srcHeight);
                } else {
                    final int srcRectHeight = (int) (srcWidth / dstAspect);
                    final int scrRectTop = (int) (srcHeight - srcRectHeight) / 2;
                    return new Rect(0, scrRectTop, srcWidth, scrRectTop
                            + srcRectHeight);
                }
            } else {
                return new Rect(0, 0, srcWidth, srcHeight);
            }
        }
    
        public static Rect calculateDstRect(int srcWidth, int srcHeight,
                int dstWidth, int dstHeight, ScalingLogic scalingLogic) {
            if (scalingLogic == ScalingLogic.FIT) {
                final float srcAspect = (float) srcWidth / (float) srcHeight;
                final float dstAspect = (float) dstWidth / (float) dstHeight;
    
                if (srcAspect > dstAspect) {
                    return new Rect(0, 0, dstWidth, (int) (dstWidth / srcAspect));
                } else {
                    return new Rect(0, 0, (int) (dstHeight * srcAspect), dstHeight);
                }
            } else {
                return new Rect(0, 0, dstWidth, dstHeight);
            }
        }
    
    }
    

    希望对你有帮助。

    谢谢。

    【讨论】:

      【解决方案2】:

      你能不使用Bitmap.createScaledBitmap方法吗?

      int srcWidth = srcBitmap.getWidth();
      int srcHeight = srcBitmap.getHeight();
      int dstWidth = (int)(srcWidth*0.8f);
      int dstHeight = (int)(srcHeight*0.8f);
      Bitmap dstBitmap = Bitmap.createScaledBitmap(srcBitmap, dstWidth, dstHeight, true);
      

      【讨论】:

      • 最佳答案在这里 :)
      • 请注意,这不尊重原始位图的纵横比
      【解决方案3】:

      我认为您可能误解了 inSampleSize 的意义。它旨在节省内存。如果您只是想以 80% 的大小绘制图像,那么您可以在将文件读入内存后使用矩阵将其缩小(或放大)。

      【讨论】:

      • 调整大小会按比例缩放吗?
      • 如果您使用矩阵缩放图像,如果您在 scale 调用中为两个参数使用相同的浮点数,它将被缩放。这是一个例子...stackoverflow.com/questions/8722359/…
      • 感谢您与我分享您的知识,也 +1。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-11
      • 1970-01-01
      • 2016-01-06
      • 1970-01-01
      • 2012-09-30
      • 2011-09-18
      • 1970-01-01
      相关资源
      最近更新 更多