有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

为了选择内容,我将ImageView类划分为子类,使其实现OnTouchListener,以便在其上绘制一个由用户决定边界的矩形

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

enter image description here

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

我遵循了especially herebut also here所述的方法,但并不完全满意,因为在我看来,像素和ImageView上的点之间的对应是1对1的,并且没有给出原始图像上与所选区域对应的所有像素

调用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);
    }   
}

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


添加了解释

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

I need to do some image processing on the selected part, and want to be sure that all the pixels in the rectangle get processed.

The image processing will be done on a server but it needs to know exactly which pixels to process. Server works with image with real dimensions, 安卓 app just tells which pixels to process to the server by passing a vector containing the pixel coordinates

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

The answers given transform coordinates with a 1 to 1 fashion. This approach clearly is not valid for my task, since an area of say 50 points in the ImageView of a certain size on the screen cannot correspond to an area of the same number of pixels in the real image, but should consider the different aspect ratio.

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

enter image description here


共 (1) 个答案

  1. # 1 楼答案

    马特奥

    这似乎更像是一个问题,你可以(主观地)容忍你发送给服务器的像素有多大的错误。事实仍然是,对于任何长宽比都不是一个好的整洁整数的情况,您必须决定“推”选择框的方向

    您链接的解决方案是非常好的解决方案。你必须扪心自问:用户会注意到我处理的图像是否与屏幕上显示的选择框相差一个像素吗?我猜可能不是。我无法想象用户在触摸屏上用他们的大胖手指选择一个矩形时会有这样的像素精度:D

    既然是这样,我就让转换为整数时发生的floor()处理最终传递给服务器的像素

    让我们看一个例子

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

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

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

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

    一些又好又丑的数字。ImageView中的任何像素都将对应于位图中的一个像素,如下所示:

    BitmapPixelX = ImageViewPixelX * WidthRatio
    BitmapPixelY = ImageViewPixelY * HeightRatio
    

    现在,我把这个位图放在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,我们将把pixel (119, 8)发送到服务器进行处理。如果我们要ceil()这些值,我们将把像素(120,9)发送到服务器进行处理这是完全由你决定的部分

    你将(几乎)总是落在像素的某个小数部分。无论你发送的像素,你的土地,或旁边的一个是你的电话。我想说的是,你的用户将完全看不到这一点,所以重申一下,让转换为整数时发生的floor()处理它

    希望有帮助

    [编辑]

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

    您的意思是位图中有176个像素,ImageView中有400个像素。因此,从一个像素到另一个像素的映射不是1:1,这将导致在确定要提取哪些像素进行处理时出现问题

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

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