简体   繁体   中英

Scaling an image to be the width of a custom view

I'm working on a custom view that's giving me unexpected results. What I'm trying to make happen is to fill a picture the width of the view and scale it keeping its aspect ratio, but it's doing something weird...

Here's what my generated log is spitting out.

  • View size: 768x942
  • Pic is portrait
  • Original Size: 960x1280 Scaled: 768x768
  • Scaled bitmap: 768x768

Now let me explain whats the log is saying according to the code. First we let the view onMeasure itself and once it's done that we're allowed to grab the width and height of the view. Next we check if the picture is landscape or portrait. Then we just do the math to find the size we need to scale to. After the math is done we create a new scaled bitmap with the results. The width is right but the height should be 1024 not 768. I can't see where its messing up.

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

}
}

The issue here is with the image ratio computation. Bitmap.getHeight() and getWidth() return ints, which makes the result of

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

be 1 for an image that is 960x1280 .

There are several options around this. You can make a float division by converting the return value of getHeight() and getWidth() :

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

Or you can simply start by the multiplication :

reqHeight = (reqWidth * this.mOriginalBitmap.getHeight()) / this.mOriginalBitmap.getWidth();
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);
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM