检查像素的出现

时间:2014-08-10 02:50:37

标签: c bitmap pixel bmp

我有以下代码:

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个垂直像素时,程序才会检测像素。

而不是:

  

程序必须检测指定像素的第一次出现。

并质疑:

  

我做错了什么?

更新

如果要缓冲然后渲染图像,它似乎有效。

2 个答案:

答案 0 :(得分:1)

你应该使用标题中的值,而不是“魔法”。数字。例如,图像的宽度和高度以及像素数据开始的偏移量。

有关格式的说明,请查看here

答案 1 :(得分:0)

您声明您“知道”每行都填充到DWORD,但没有迹象表明您使用这些知识。

您的图片宽50像素;从尝试使用“每像素位数”(bpx)[1],我推断图像每像素使用3个字节。因此,每行为150字节,向上舍入为152字节。这就是你的bmp_find_xy函数返回错误地址的原因。

计算行宽的正确方法是:

  1. 每个像素乘以 bytes ;
  2. 如果结果是4的倍数,则完成;
  3. 其他向上舍入到4的倍数。
  4. 你的功能,根据这些知识调整:

    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文件具有其他每像素位数,但如果您希望代码适用于所有可能的图像,您可能希望 一个。确保它首先适用于简单,硬编码的案例;和
    湾您从结构BMPDIB中读取所有必要信息。

    [2]为什么2+在那里?这表示要么你的BMP和/或DIB的大小已关闭,(很有可能)你捏造了这个,因为你无法得到你的代码没有工作。