用于查找像素的xy位置的函数

时间:2014-08-11 00:08:26

标签: c bitmap bmp

因为我之前的问题肯定不是很干净。分别我无法实现我的问题的精确解决方案。我一直在研究一个函数,它返回位于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; 
}

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

1 个答案:

答案 0 :(得分:3)

您的代码看起来像是给我正确的结果。然而它本身并不一致。

  • 在行(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; 

此外,您还可以从标题中读取宽度,通道和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!为此使用库!