ImageView坐标和位图像素之间的对应关系 - Android

Mat*_*teo 12 java android android-image android-imageview

在我的应用程序中,我希望用户能够选择一个包含在其中的图像的某些内容ImageView.

要选择内容,我将该ImageView类子类化,使其实现,OnTouchListener以便在其上绘制一个由用户决定的带边框的矩形.

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

enter image description here

现在我需要确定哪些像素的的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);
    }   
}
Run Code Online (Sandbox Code Playgroud)

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


增加了解释

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

我需要对选定的部分进行一些图像处理,并且要确保处理矩形中的所有像素.

图像处理将在服务器上完成,但需要确切知道要处理的像素.服务器使用具有真实尺寸的图像,android app通过传递包含像素坐标的矢量来告诉处理服务器的像素

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

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

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

enter image description here

Ter*_*ate 15

利玛窦,

看起来这更像是一个问题,即你可以(主观地)容忍你发送到服务器的像素有多少错误.事实仍然是,对于任何宽高整数都没有出现的宽高比,你必须决定"推"选择框的方向.

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

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

我们来看一个例子.

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

ImageViewWidth = 400, ImageViewHeight = 150
BitmapWidth = 176, BitmapHeight = 65
Run Code Online (Sandbox Code Playgroud)

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

WidthRatio = BitmapWidth / ImageViewWidth = 175 / 400 = 0.44
HeightRatio = BitmapHeight / ImageViewHeight = 65 / 150 = 0.44
Run Code Online (Sandbox Code Playgroud)

一些不错的丑陋数字.无论我在ImageView中使用哪个像素都将对应于位图中的像素,如下所示:

BitmapPixelX = ImageViewPixelX * WidthRatio
BitmapPixelY = ImageViewPixelY * HeightRatio
Run Code Online (Sandbox Code Playgroud)

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

RectTopLeftX = 271, RectTopLeftY = 19
RectBottomRightX = 313, RectBottomRightY = 42
Run Code Online (Sandbox Code Playgroud)

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

RectTopLeftX * WidthRatio = 271 * .44 = 119.24
RectTopLeftY * HeightRatio = 19 * .44 = 8.36
Run Code Online (Sandbox Code Playgroud)

对于RectTopLeftX,我们发现自己的BitmapPixelX值为119,然后大约是像素的四分之一.好吧,如果我们floor()这个值和相应的BitmapPixelY值为8.36,我们将发送像素(119, 8)到服务器进行处理.如果我们使用ceil()这些值,我们将向服务器发送像素(120,9)进行处理.这部分完全取决于您.

你(几乎)总是落在一个像素的一些小部分.无论您发送的是您登陆的像素,还是旁边的像素都是您的通话.我会说这会让你的用户完全不知道,所以重申一下,只要让floor()在转换为整数时发生的-ing处理它.

希望有所帮助!

[编辑]

在再次慢慢阅读问题时,我想我更能理解你的疑问/困惑.我将用上面的例子来说明.

你是说Bitmap中有176个像素,ImageView中有400个像素.因此,从一个到另一个的映射不是1:1,这将在确定要拉出哪些像素进行处理时引起问题.

但事实并非如此!当您将ImageView中矩形边界的坐标转换为位图中的坐标时,您只需在Bitmap中提供迭代的像素范围.它不是描述ImageView中每个像素如何映射到位图中的相应像素.

我希望这能让我对你的困惑感到困惑.