【问题标题】:Scaling an image to be the width of a custom view将图像缩放为自定义视图的宽度
【发布时间】:2014-09-25 15:03:23
【问题描述】:

我正在开发一个自定义视图,它会给我带来意想不到的结果。我想要实现的是将图片填充到视图的宽度并对其进行缩放以保持其纵横比,但它正在做一些奇怪的事情......

这是我生成的日志吐出的内容。

  • 视图尺寸:768x942
  • 图片为纵向
  • 原始尺寸:960x1280 缩放:768x768
  • 缩放位图:768x768

现在让我根据代码解释一下日志在说什么。首先,我们让视图onMeasure 本身,一旦完成,我们就可以获取视图的宽度和高度。接下来我们检查图片是横向还是纵向。然后我们只是做数学来找到我们需要缩放到的大小。数学计算完成后,我们用结果创建一个新的缩放位图。宽度是正确的,但高度应该是 1024 而不是 768。我看不出它在哪里搞砸了。

public void setBitmap(Bitmap bmp) {
this.mOriginalBitmap = bmp;

if(mHasMeasured) {
    //Make sure the view has measured itself so we can grab the width and height
Log.d("", "View size: " + String.valueOf(this.mViewWidth)
+ "x" + String.valueOf(this.mViewHeight));

int reqWidth, reqHeight; //The required sizes we need

//Get the new sizes for the pic to fit in the view and keep aspect ratio
if(this.mOriginalBitmap.getWidth() > this.mOriginalBitmap.getHeight()) {
//Landscape :/
Log.d("", "Pic is Landscape");


reqHeight = this.mViewHeight;

reqWidth = (this.mOriginalBitmap.getWidth()
             / this.mOriginalBitmap.getHeight()) * reqHeight;

} else {
//Portrait :)
Log.d("", "Pic is portrait");

reqWidth = this.mViewWidth;

reqHeight = (this.mOriginalBitmap.getHeight()
             / this.mOriginalBitmap.getWidth()) * reqWidth;

}




Log.d("", "Original Size: "
             + String.valueOf(mOriginalBitmap.getWidth()) + "x"
             + String.valueOf(mOriginalBitmap.getHeight())
             + " Scaled: " + String.valueOf(reqWidth)
             + "x" + String.valueOf(reqHeight) );

this.mBmpScaledForView = Bitmap.createScaledBitmap(mOriginalBitmap,
         reqWidth, reqHeight, false);

this.mSrc.top = 0;
this.mSrc.left = 0;
this.mSrc.right = this.mBmpScaledForView.getWidth();
this.mSrc.bottom = this.mBmpScaledForView.getHeight();
this.mDst = this.mSrc; 

Log.d("", "Scaled bitmap : "
             + String.valueOf(this.mBmpScaledForView.getWidth())
             + "x" + String.valueOf(this.mBmpScaledForView.getHeight()));

}
}

【问题讨论】:

  • 整数除法问题。 Bitmap.getHeight 返回一个 int,所以 getHeight/getWidth 为 1,这导致 reqWidth == reqHeight
  • 啊!好的,那么使用浮点数?
  • 或者简单地反转你的操作:reqHeight = (reqWidth * this.mOriginalBitmap.getHeight()) / this.mOriginalBitmap.getWidth();
  • 太棒了!解决了它!请回答。
  • 你为什么要使用 Bitmap.createScaledBitmap?为什么在绘制位图时不使用矩阵?

标签: android android-bitmap


【解决方案1】:

这里的问题在于图像比例计算。 Bitmap.getHeight()getWidth() 返回整数,这使得结果为

(this.mOriginalBitmap.getHeight()
         / this.mOriginalBitmap.getWidth())

对于960x1280 的图像,请使用1

有几个选项可以解决这个问题。您可以通过转换getHeight()getWidth()的返回值来进行float除法:

((float) this.mOriginalBitmap.getHeight()
         / (float) this.mOriginalBitmap.getWidth())

或者你可以简单地从乘法开始:

reqHeight = (reqWidth * this.mOriginalBitmap.getHeight()) / this.mOriginalBitmap.getWidth();

【讨论】:

    【解决方案2】:
    package com.riktamtech.app.utils;
    
    import android.content.Context;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.widget.ImageView;
    
    /**
     * ImageView that keeps aspect ratio when scaled
     */
    
    public class CustomImageView extends ImageView {
    
        public CustomImageView(Context context) {
            super(context);
        }
    
        public CustomImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            try {
                Drawable drawable = getDrawable();
                if (drawable == null) {
                    setMeasuredDimension(0, 0);
                } else {
                    int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
                    int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
                    if (measuredHeight == 0 && measuredWidth == 0) { // Height and
                                                                        // width set
                                                                        // to
                                                                        // wrap_content
                        setMeasuredDimension(measuredWidth, measuredHeight);
                    } else if (measuredHeight == 0) { // Height set to wrap_content
                        int width = measuredWidth;
                        int height = width * drawable.getIntrinsicHeight()
                                / drawable.getIntrinsicWidth();
                        setMeasuredDimension(width, height);
                    } else if (measuredWidth == 0) { // Width set to wrap_content
                        int height = measuredHeight;
                        int width = height * drawable.getIntrinsicWidth()
                                / drawable.getIntrinsicHeight();
                        setMeasuredDimension(width, height);
                    } else { // Width and height are explicitly set (either to
                                // match_parent or to exact value)
                        setMeasuredDimension(measuredWidth, measuredHeight);
                    }
                }
            } catch (Exception e) {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-22
      • 1970-01-01
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多