12

在我的应用程序中,我希望用户能够选择包含在ImageView.

为了选择内容,我对类进行了子ImageView类化,使其实现了OnTouchListener在其上绘制一个由用户决定边框的矩形。

这是绘图结果的示例(要了解它的工作原理,您可以将其想象为在桌面上单击鼠标并拖动鼠标时):

在此处输入图像描述

现在我需要确定图像的哪些像素Bitmap对应于所选部分。确定哪些点属于矩形很容易ImageView,但我不知道如何获得对应的像素,因为ImageView它的纵横比与原始图像不同。

我遵循了这里特别描述的方法,但也没有完全满意,因为在我看来,像素和点之间的对应关系是 1 对 1 的,ImageView并且不会将原始图像上的所有对应像素都提供给所选的区域。

在其中的点上调用hoveredRect矩形是:ImageView

class Point {
    float x, y;
    @Override
    public String toString() {
        return x + ", " + y;
    }
}

Vector<Point> pointsInRect = new Vector<Point>();

for( int x = hoveredRect.left; x <= hoveredRect.right; x++ ){
    for( int y = hoveredRect.top; y <= hoveredRect.bottom; y++ ){

        Point pointInRect = new Point();
        pointInRect.x = x;
        pointInRect.y = y;
        pointsInRect.add(pointInRect);
    }   
}

如何获得Vector<Pixels> pixelsInImage包含图像对应像素的a Bitmap


附加说明

我将更好地解释我的问题的背景:

我需要对所选部分进行一些图像处理,并希望确保矩形中的所有像素都得到处理。

图像处理将在服务器上完成,但它需要确切知道要处理哪些像素。服务器处理具有真实尺寸的图像,android 应用程序只是通过传递包含像素坐标的向量来告诉服务器要处理哪些像素

以及为什么我不喜欢上面链接中提出的解决方案:

给出的答案以 1 对 1 的方式变换坐标。这种方法显然对我的任务无效,因为ImageView屏幕上某个大小的 50 个点的区域不能对应于真实图像中相同数量像素的区域,但应该考虑不同的纵横比。

例如,如果图像小于ImageView应用程序上显示的区域,则应选择以下区域:

在此处输入图像描述

4

3 回答 3

15

马特奥,

似乎这更多的是一个问题,即您可以(主观地)容忍您发送到服务器的像素有多少。事实仍然是,对于任何没有得到一个很好的整数的纵横比,您必须决定“推动”选择框的哪个方向。

您链接到的解决方案是非常好的解决方案。您必须问自己:如果我处理的图像与屏幕上显示的选择框相差一个像素,用户会注意到吗?我的猜测可能不是。我无法想象用户在触摸屏上用粗大的手指选择矩形时无论如何都会有那种像素精度:D

既然是这种情况,我只会让floor()在转换为整数时发生的 -ing 处理您最终传递给服务器的像素。

让我们看一个例子。

让我们将 ImageView 和 Bitmap 的宽度和高度定义为:

ImageViewWidth = 400, ImageViewHeight = 150
BitmapWidth = 176, BitmapHeight = 65

然后,您将用于在它们之间转换选择框的纵横比将是:

WidthRatio = BitmapWidth / ImageViewWidth = 175 / 400 = 0.44
HeightRatio = BitmapHeight / ImageViewHeight = 65 / 150 = 0.44

一些漂亮丑陋的数字。我在 ImageView 中的任何像素都将对应于 Bitmap 中的像素,如下所示:

BitmapPixelX = ImageViewPixelX * WidthRatio
BitmapPixelY = ImageViewPixelY * HeightRatio

现在,我将这个 Bitmap 放在 ImageView 的屏幕上,供用户选择一个矩形,用户在 ImageView 中选择一个具有左上角和右下角坐标的矩形,如下所示:

RectTopLeftX = 271, RectTopLeftY = 19
RectBottomRightX = 313, RectBottomRightY = 42

如何确定这些对应于位图中的哪些像素?简单的。我们之前确定的比率。现在让我们只看左上角的坐标。

RectTopLeftX * WidthRatio = 271 * .44 = 119.24
RectTopLeftY * HeightRatio = 19 * .44 = 8.36

对于 RectTopLeftX,我们发现自己的 BitmapPixelX 值为 119,然后进入像素的四分之一左右。好吧,如果我们把floor()这个值和对应的BitmapPixelY 值设为8.36,我们就会将像素发送(119, 8)到服务器进行处理。如果我们要ceil()这些值,我们将把像素 (120, 9) 发送到服务器进行处理。这完全取决于您。

您将(几乎)总是落在像素的某个小数部分。无论您发送您登陆的像素,还是它旁边的像素都是您的电话。我想说这将完全不会被您的用户注意到,因此重申一下,只需让floor()在转换为整数时发生的 -ing 处理它。

希望有帮助!

[编辑]

在更慢地再次阅读这个问题后,我想我更好地理解你在问什么/困惑什么。我将用我上面的例子来说明。

您是说位图中有 176 个像素,而 ImageView 中有 400 个像素。因此,从一个到另一个的映射不是 1:1,这在确定要提取哪些像素进行处理时会产生问题。

但事实并非如此!当您将 ImageView 中矩形边界的坐标转换为 Bitmap 中的坐标时,您只是给出了要在 Bitmap中迭代的像素范围它不是对 ImageView 中的每个单独像素如何映射到 Bitmap 中相应像素的描述。

我希望这能消除我对你的困惑的困惑。

于 2012-07-24T20:23:47.067 回答
2

这可以通过非常简单的数学来解决,您的矩形有 4 个点 p1、p2、p3、p4,坐标为 x、y,相对于 ImageView。

您还知道原始图像的尺寸。

现在,例如,如果 p1.x 为 50,在 200 px 宽的 ImageView 中,您将得到 50 / 200 = 0.25 的关系

如果您的原始图像是 100 像素宽,您的点 p1.x 将位于 100 * 0.25 = 25 像素

可以表示:

50 -> 200

? -> 100

并计算:

? = 100 * 50 / 200

您对每个点、每个维度 x、y 执行此操作,然后您将获得原始图像中矩形的 4 个点。

现在,如果您使用这些计算点进行迭代,您应该得到原始图像中矩形的像素。

于 2012-07-04T21:07:06.183 回答
0

在这里,我假设您在图像视图中放置了一些东西。在 onCreate 中执行此操作:

ImageView image=(ImageView) findViewById(R.id.imageView1);
TextView coordinates=(TextView) findViewById(R.id.textView1);
bitmap = ((BitmapDrawable)Map.getDrawable()).getBitmap();

这在onTouch里面:

coordinates.setText("Touch coordinates:"+String.valueOf(event.getX())+"x"+String.valueOf(event.getY()));
int pixel = bitmap.getPixel((int)event.getX(), (int)event.getY());

现在你有了你想要的特定像素。

于 2012-07-24T23:00:00.740 回答