Android:如何在onDraw()中获取位图的缩放宽度

5
简单的问题却无法得到简单的答案。我有一个位图,我想在onDraw()方法中获取它的尺寸,以便按系统缩放到不同DPI屏幕上显示。bitmap.width()成功地返回其未缩放的宽度。然而,bitmap.getScaledWidth()返回0。我已经尝试了getScaledWidth(canvas)和getScaledWidth(canvas.getDensity()),但都返回0。事实上,canvas.getDensity()返回0,所以我甚至不能手动计算它。
我做错了什么?
稍微详细一点。我正在使用自定义视图。该位图在类中声明并在构造函数中加载。
编辑:
我发现使用:
        DisplayMetrics metrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(metrics);

bitmap.getScaledHeight(metrics)返回的值与bitmap.getHeight()相同。

看起来,bitmap.getWidth()返回的是经过缩放后的位图的尺寸,这意味着没有明显的方法来获取位图的原始宽度。


1
你是如何对位图进行缩放的? - mc_fish
你是使用 new Canvas() 获取密度还是使用 onDraw(Canvas) 接收的那个? - harism
通过缩放,我指的是Android系统自动将位图缩放到显示DPI。我正在使用onDraw(Canvas canvas)中的画布。我将该画布传递给getSacledWidth(canvas)方法,但它返回零。 - Tickled Pink
2个回答

5
Canvas类有很多drawBitmap()函数的重载。其中一个允许你通过非常方便的接口来缩放/剪切位图。

public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint)

其中

  • Bitmap bitmap - 你要绘制的位图
  • Rect src - 从你的位图中获取的源矩形。如果不为null,它将从你的位图中剪切出一块(大小和位置与src相同)
  • RectF dst - 这个矩形代表你的位图适合的矩形。
  • Paint paint - 可选的画笔

现在来看一个例子!假设你想将你的位图的宽度缩小到原来的1/2,并将其高度增加到原来的2倍:

float startX = 0; //the left
float startY = 0; //and top corner (place it wherever you want)
float endX = startX + bitmap.getWidth() * 0.5f; //right
float endY = startY + bitmap.getHeight() * 2.0f; //and bottom corner

canvas.drawBitmap(bitmap, null, new RectF(startX, startY, endX, endY), null);

更新

在阅读了您的评论后,我并没有完全理解您想要实现的目标,但是这里有一些额外的信息可以帮助您开始:

获取位图的原始大小而不将其加载到内存中:

BitmapFactory.Options options = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = true; // bitmap wont be loaded into the memory

//won't load the Bitmap, but the options will contain the required information.
BitmapFactory.decodeStream(inputStream, null, options);
/*or*/ BitmapFactory.decodeFile(pathName, options);

int originalWidth = bitmapOptions.outWidth;
int originalHeight = bitmapOptions.outHeight;

现在,如果您有另一个实际的(缩放后的)BitmapImageView,想要将其与原始图像进行比较,那么您可以使用以下代码(要获取宽度和高度,请使用getWidth()getHeight()):
/*Get these values*/
int originalWidth, originalHeight, scaledWidth, scaledHeight; 

float scaleWidthRatio = (float)scaledWidth / originalWidth;
float scaleHeightRatio = (float)scaledHeight / originalHeight;

谢谢,但我不想在绘图时缩放位图,而是想知道系统如何缩放以匹配屏幕DPI。例如,如果我有一个为160 DPI屏幕创建的图形,并在120 DPI屏幕上显示,则需要获取它已经缩小了多少(应返回0.75或类似值),以便我可以按相同比例缩放其他因素。 - Tickled Pink
是的,我之前刚刚发现了这个。;) 实际上,位图默认情况下会被加载和缩放,但是使用bitmapfactory.options,可以控制它们的加载方式,包括未经缩放的加载和手动缩放,这就是其他人建议的内容。在Android中,我所需要的并没有明确提供,因此我们使用这些解决方法。 - Tickled Pink

1
这样怎么样?你自己缩放位图。 :-)
protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);
        Drawable drawable = getDrawable();
        if(drawable==null)
            Log.d("onDraw()","getDrawable returns null");

        Bitmap  fullSizeBitmap,scaledBitmap = null,roundBitmap = null;

        fullSizeBitmap = ((BitmapDrawable)drawable).getBitmap() ;

        //get width & height of ImageView
        int scaledWidth = getMeasuredWidth();
        int scaledHeight = getMeasuredHeight();

        //bitmap, which will receive the reference to a bitmap scaled to the bounds of the ImageView.
        if(fullSizeBitmap!=null)
        scaledBitmap= getScaledBitmap(fullSizeBitmap,scaledWidth,scaledHeight);

        //Now, draw the bitmap on the canvas
        if(roundBitmap!=null)
           canvas.drawBitmap(roundBitmap, 0,0 , null);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接