我有以下代码:
typedef unsigned char BYTE;
typedef unsigned long dword;
dword bmp_find_xy (dword xp, dword yp)
{
dword w = 50;
word bpx = (3*8);
dword offset = (2+sizeof(BMP)+sizeof(DIB));
dword row = (((bpx * w) * 4) / 32);
dword pixAddress = (offset) + row * yp + ((xp * bpx) / 8);
return pixAddress;
}
/*--------------------------------------------------------------------*/
dword bmp_dfind_c (BYTE R, BYTE G, BYTE B)
{
dword w = 50;
dword h = 50;
dword size;
FILE* fp = fopen("picture.bmp", "r+b");
BYTE* bmp;
int W, H, i;
dword row = (((24 * w) * 4) / 32);
/*---------------------------------------------------------------------*/
fseek(fp, 0L, SEEK_END); size = ftell(fp); bmp = malloc(size);
rewind(fp);
for(i=0; i<size; i++)
bmp[i] = fgetc(fp);
fseek(fp, 54, SEEK_SET);
H = h;
while (H--)
{
for(W = 0; W < w; W++)
{
if(bmp[bmp_find_xy(W, H)] == B &&
bmp[bmp_find_xy(W, H)+1] == G &&
bmp[bmp_find_xy(W, H)+2] == R) {
printf("%i %i %i pixel first occurance at: x:%i y:%i", R, G, B, W, H); }
}
}
fclose(fp);
return 1;
}
似乎我忘记了如何准确存储bmp像素。我知道它有填充..我没有在代码中实现。也许这就是我遇到问题的原因。 只有当我在图像中放置3个垂直像素时,程序才会检测像素。 程序必须检测指定像素的第一次出现。 我做错了什么?
如何接近(1)因为它不清楚我在问什么? 我问道: 为什么这段代码的行为如下:
只有当我在图像中放置3个垂直像素时,程序才会检测像素。
而不是:
程序必须检测指定像素的第一次出现。
并质疑:
我做错了什么?
更新
如果要缓冲然后渲染图像,它似乎有效。
答案 0 :(得分:1)
你应该使用标题中的值,而不是“魔法”。数字。例如,图像的宽度和高度以及像素数据开始的偏移量。
有关格式的说明,请查看here。
答案 1 :(得分:0)
您声明您“知道”每行都填充到DWORD,但没有迹象表明您使用这些知识。
您的图片宽50像素;从尝试使用“每像素位数”(bpx
)[1],我推断图像每像素使用3个字节。因此,每行为150字节,向上舍入为152字节。这就是你的bmp_find_xy
函数返回错误地址的原因。
计算行宽的正确方法是:
你的功能,根据这些知识调整:
dword bmp_find_xy (dword xp, dword yp)
{
dword w = 50;
dword offset = 2+sizeof(BMP)+sizeof(DIB); /* SEE [2]! */
dword row = 3 * w;
if (row & 3)
{
row += 4;
row &= ~3;
}
dword pixAddress = offset + row * yp + xp;
return pixAddress;
}
备注:强>
[1]此处不需要调整bpx
。您的图像是一个24位全彩色图像,并且整齐地转换为3个字节,因此不需要乘以8 * 3再次除以8。当然,BMP文件具有其他每像素位数,但如果您希望代码适用于所有可能的图像,您可能希望
一个。确保它首先适用于此简单,硬编码的案例;和
湾您从结构BMP
和DIB
中读取所有必要信息。
[2]为什么2+
在那里?这表示要么你的BMP
和/或DIB
的大小已关闭,或(很有可能)你捏造了这个,因为你无法得到你的代码没有工作。