【发布时间】:2011-02-17 19:40:39
【问题描述】:
我有一个比我放入的 ImageView 更大的位图。我将 ScaleType 设置为 center_inside。如何获得按比例缩小的图像的尺寸?
【问题讨论】:
我有一个比我放入的 ImageView 更大的位图。我将 ScaleType 设置为 center_inside。如何获得按比例缩小的图像的尺寸?
【问题讨论】:
好的。我可能应该更清楚。在将缩放位图绘制到屏幕之前,我需要它的高度和宽度,以便我可以在正确的位置绘制一些叠加层。我知道原始位图中叠加层的位置,但不知道缩放的位置。我想出了一些简单的公式来计算它们在缩放位图上的位置。
我会解释我做了什么,以防其他人有一天需要这个。
我得到了位图的原始宽度和高度。 ImageView 的高度和宽度在 xml 文件中硬编码为 335。
int bitmap_width = bmp.getWidth();
int bitmap_height = bmp.getHeight();
我确定了哪一个更大,这样我就可以正确地确定计算的基础是哪一个。对于我当前的示例,宽度更大。由于宽度被缩小到 ImageView 的宽度,我必须找到缩小的高度。我只是将 ImageView 的宽度与 Bitmap 的宽度之比乘以 Bitmap 的高度。除法是最后完成的,因为先进行整数除法会导致答案为 0。
int scaled_height = image_view_width * bitmap_height / bitmap_width;
使用缩放高度,我可以使用以下方法确定缩放位图两侧的空白空间量:
int blank_space_buffer = (image_view_height - scaled_height) / 2;
要确定覆盖在缩放位图上的位置的 x 和 y 坐标,我必须使用原始坐标和这些计算得出的数字。本例中的 x 坐标很简单。由于缩放后的宽度是 ImageView 的宽度,所以我只需要将 ImageView 的宽度与 Bitmap 的宽度之比乘以原始 x 坐标即可。
int new_x_coord = image_view_width * start_x / bitmap_width;
y 坐标有点棘手。取位图的缩放高度与位图原始高度的比率。将该值与原始 y 坐标相乘。然后添加空白区域缓冲区。
int new_y_coord = scaled_height * start_y / bitmap_height + blank_space_buffer;
这可以满足我的需要。如果高度大于宽度,只需反转宽度和高度变量即可。
【讨论】:
我是这样做的:
ImageView iv = (ImageView)findViewById(R.id.imageview);
Rect bounds = iv.getDrawable().getBounds();
int scaledHeight = bounds.height();
int scaledWidth = bounds.width();
如果要获取原始大小,可以使用Drawable的getIntrinsicWidth()或height方法。
编辑:好的,如果您在 onCreate 运行时尝试访问这些边界,则必须等待并检索它们,直到布局通过之后。虽然我不知道这是最好的方法,但这就是我能够完成它的方式。基本上,向 ImageView 添加一个侦听器,并在将其绘制到屏幕之前获取您的尺寸。如果您需要对检索到的尺寸进行任何布局更改,您应该在 onPreDraw() 中进行。
ImageView iv = (ImageView)findViewById(R.id.imageview);
int scaledHeight, scaledWidth;
iv.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
Rect rect = iv.getDrawable().getBounds();
scaledHeight = rect.height();
scaledWidth = rect.width();
iv.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
});
【讨论】:
试试这个代码:
final ImageView iv = (ImageView) findViewById(R.id.myImageView);
ViewTreeObserver vto = iv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Toast.makeText(MyActivity.this, iv.getWidth() + " x " + iv.getHeight(), Toast.LENGTH_LONG).show();
iv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
否则,您可以通过将此视图设为自定义视图来使用onSizeChange()。
【讨论】: