【问题标题】:Function to find the xy location of a pixel查找像素xy位置的函数
【发布时间】:2014-08-11 00:08:26
【问题描述】:

因为我之前的问题肯定不是很干净。并且分别我无法实现我的问题的确切解决方案。我一直在研究一个函数,它返回位于 X/Y 坐标中的像素的字节偏移量。为此,我有:

dword bmp_find_xy (dword xp, dword yp)
{
    dword w = 50; // to clarify thats the real widh of the sample image i use
    dword bpx = (3*8); // using 3*8 as a reminder.
    dword offset = (2+sizeof(BMP)+sizeof(DIB)); // this is the offset 54.
    dword pitch = w * 3; // determining the widh of pixels. Pitch variable
    dword row = w * 3; // determining the widh of pixels. Row variable.
    dword pixAddress; // result variable

    if(pitch % 4 != 0) pitch += 4 - (pitch % 4); // finding the pitch (row+padding)
    pixAddress = (offset) + pitch * yp + ((xp * bpx) / 8); // finding the address

    return pixAddress; 
}

所以问题不会像“我做错了什么/为什么我收到奇怪的错误”。问题是..我做得对吗?在第一次测试中,它似乎有效。但我有点不确定。一旦确认这是正确的方法..我将删除问题。

【问题讨论】:

  • 我需要一堂关于位图理论的课程,因为我的知识当然不足以帮助你。
  • @FiddlingBits 这很容易,但确实令人困惑。顺便说一句,我不是母语……这让情况变得更糟。不……只是我不能发布整个项目。没有人能够编译它。它用于自定义引擎。
  • 我没想到你不是以英语为母语的人,所以……没什么好担心的。 :-D
  • 我正在尽力...
  • 您正在硬编码pitch,但有这样的声明:if(pitch % 4 != 0) ...;。这始终是正确的,因为 150 不能被 4 整除。

标签: c bitmap bmp


【解决方案1】:

您的代码看起来给了我正确的结果。但是它本身是不一致的。

  • 在行 (yp) 寻址中,您假设每个像素都有 3 个字节。
  • 在列 (xp) 寻址中,您假设每个像素都有 3*8 位。

那么为什么在第一种情况下使用字节,在第二种情况下使用位?我认为代码会像这样更干净:

dword width = 50; // image width
dword channels = 3; // number of color channels
dword bpp = 8; // depth in bits

dword single = (channels*bpp)/8; // size of a pixel in bytes
dword offset = (2+sizeof(BMP)+sizeof(DIB)); // this is the offset 54.
dword rowsize = width*single; // size of a row in memory
if (rowsize % 4 != 0)
    rowsize += 4 - (rowsize % 4); // account for padding

dword pixAddress; // result variable
pixAddress = offset + yp*rowsize + xp*single; // finding the address

return pixAddress; 

另外,你可以从header中读取width、channel和bpp。

接下来,如果您首先获取一行中第一个像素的地址,然后继续遍历该行(而不是每次都重新计算整个内容),您的代码会更快。这是运行在所有像素上的典型任务的图示。请注意,我在这里没有使用与原始问题相同的编码风格。

unsigned char maxGreen = 0;
for (int y = 0; y < height; y++) {
    unsigned char *row = bitmap.getRowPtr(y);
    for (int x = 0; x < width; x++) {
        unsigned char *pixel = row + bitmap.getColumnOffset(x);
        if (pixel[2] > maxGreen)
            maxGreen = pixel[2];
    }
}
// maxGreen holds the maximum value in the green channel observed in the image

如您所见,在此示例中,偏移量、填充等计算只需在 getRowPtr() 函数中每行执行一次。对于每个像素,我们只需要在 getColumnOffset() 函数中进行偏移计算(简单的乘法运算)。 在分解每个像素需要进行多少计算时,这使得示例速度更快。

最后,我绝不会自己编写代码来读取 BMP!为此使用图书馆!

【讨论】:

  • 我这样做是有原因的。我没有从标题中读取值,因为我删除了它以使其在这里变得简单。而且我不能使用库,因为没有人与我使用的引擎兼容。这就是为什么我自己做。 +1 确认和建议。但是..我无法理解代码速度更快的事情。
  • 大多数情况下,您在位图上操作会遍历所有像素。例如,在 xp 上的 for 循环周围有一个 yp 上的 for 循环。在这种情况下,明智的做法是在外循环中获取行的开头并将其用作内循环的基础。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多