在更大的bmp文件中查找一个小bmp文件

时间:2014-07-19 17:28:14

标签: c++ bmp

我想从另一个更大的bmp文件中找到一个小bmp文件(较大的一个从屏幕捕获并称为Sample.bmp,小bmp文件称为Button.bmp。事情是比较文件的图像时在任何地方都找不到。

比较代码:

for (int i=0;i<SCREEN_WIDTH-width;++i)
        {
            for (int j=0;j<SCREEN_HEIGHT-height;++j)
            {
                boolean isequal = true;
                for(int qqq=i;qqq<i+width;++qqq)
                {
                    for (int kkk=j;kkk<j+height;++kkk)
                    {
                        if (PI[qqq][kkk]!=NPI[qqq-i][kkk-j]) isequal = false;
                        if (isequal == false) 
                        {
                                qqq =  i + width + 1;
                                kkk = j + height + 1;
                        }
                    }
                }
                if (isequal==true)
                {
                    MidX = i;
                    MidY = j;
                    return;
                }
            }
        }

注意:Screen_width和Screen_height用于较大的图像,宽度和高度用于较小的图像

完整代码:

    void readBMP()
{
    int i;
    FILE* f = fopen("Sample.bmp", "rb");
    unsigned char info[54];
    fread(info, sizeof(unsigned char), 54, f); // read the 54-byte header

    // extract image height and width from header
    int width = *(int*)&info[18];
    int height = *(int*)&info[22];

    int size = 3 * width * height;
    unsigned char* data = new unsigned char[size]; // allocate 3 bytes per pixel
    fread(data, sizeof(unsigned char), size, f); // read the rest of the data at once
    fclose(f);

    for(int qq=0;qq<SCREEN_WIDTH;++qq)
        for (int kk=0;kk<SCREEN_HEIGHT;++kk)
        {
            PI[qq][kk][0] = data[kk * width + qq];
            PI[qq][kk][1] = data[kk * width + qq + 1];
            PI[qq][kk][2] = data[kk * width + qq + 2];
        }



}

void FindImageInScreen(char* FileName)
{

    FILE* f = fopen(FileName, "rb");
    unsigned char info[54];
    fread(info, sizeof(unsigned char), 54, f); // read the 54-byte header

    // extract image height and width from header
    int width = *(int*)&info[18];
    int height = *(int*)&info[22];

    int size = 3 * width * height;
    unsigned char* data = new unsigned char[size]; // allocate 3 bytes per pixel
    fread(data, sizeof(unsigned char), size, f); // read the rest of the data at once
    fclose(f);



    for(int qq=0;qq<width;++qq)
        for (int kk=0;kk<height;++kk)
        {
            NPI[qq][kk][0] = data[kk * width + qq];
            NPI[qq][kk][1] = data[kk * width + qq + 1];
            NPI[qq][kk][2] = data[kk * width + qq + 2];
        }

        for (int i=0;i<SCREEN_WIDTH-width;++i)
        {
            for (int j=0;j<SCREEN_HEIGHT-height;++j)
            {
                boolean isequal = true;
                for(int qqq=i;qqq<i+width;++qqq)
                {
                    for (int kkk=j;kkk<j+height;++kkk)
                    {
                        if (PI[qqq][kkk][0]!=NPI[qqq-i][kkk-j][0]) isequal = false;
                        if (isequal == false) 
                        {
                                qqq =  i + width + 1;
                                kkk = j + height + 1;
                        }
                    }
                }
                if (isequal==true)
                {
                    MidX = i;
                    MidY = j;
                    return;
                }
            }
        }

        MidX = -1;
        MidY = -1;
        return;

}       

数组的定义(由于请求而添加),这是在函数execute:

之前
         PI = new unsigned int**[SCREEN_WIDTH];
    for (int i=0;i<SCREEN_WIDTH;++i)
        PI[i] = new unsigned int*[SCREEN_HEIGHT];
    for (int i=0;i<SCREEN_WIDTH;++i)
        for (int j=0;j<SCREEN_HEIGHT;++j)
            PI[i][j] = new unsigned int[3];


    NPI = new unsigned int**[SCREEN_WIDTH];
    for (int i=0;i<SCREEN_WIDTH;++i)
        NPI[i] = new unsigned int*[SCREEN_HEIGHT];
    for (int i=0;i<SCREEN_WIDTH;++i)
        for (int j=0;j<SCREEN_HEIGHT;++j)
            NPI[i][j] = new unsigned int[3];

第一个函数执行第二个函数。对于一些糟糕的编程感到抱歉,因为我做了数千次更改才能使其正常工作!

2 个答案:

答案 0 :(得分:0)

PI[qq][kk][0] = data[kk * width + qq];

从填写PINPI的方式来看,它们似乎是三维数组(如果将它们的定义包含在代码示例中,它会有所帮助)。但

if (PI[qqq][kkk]!=NPI[qqq-i][kkk-j]) isequal = false;

仅索引每个的2个维度。 PI[a][b]是包含PI[a][b][0..2]的数组的地址,并且肯定永远不会匹配NPI[x][y]的地址,所以此语句总是返回false我希望。

答案 1 :(得分:0)

让我们开始吧。这是一个更好的LoadBMP 除了其他之外,你的其他东西,读取大小,无论如何使用SCREEN_HEIGHT 使用它来加载两个图像可能更容易。

#include <vector>
#include <cstdio>
#include <string>

using namespace std;

typedef unsigned char UC;

struct RGB { UC r,g,b; };
bool operator == ( const RGB& p1, const RGB& p2 ) { return p1.r==p2.r && p1.g==p2.g && p1.b==p2.b; }

struct BMP
{
    int width;
    int height;
    vector<RGB> pixels;
    RGB& Pix(int x,int y) { return pixels[ y*width + x ]; }
};

void LoadBMP( BMP& bmp, const char* filename )
{
    FILE* f = fopen(filename, "rb");
    UC info[54];
    fread(info, 1, 54, f); // read the 54-byte header

    // extract image height and width from header
    bmp.width =  *(int*) (info+18);
    bmp.height = *(int*) (info+22);

    // scanlines are always multiple of 4, padded with 0-3 bytes
    int scanlinesize = 3*bmp.width;
    while( scanlinesize % 4 ) ++scanlinesize;
    int size = scanlinesize * bmp.height;
    UC* data = new UC[size];
    fread(data, 1, size, f);
    fclose(f);

    bmp.pixels.clear();
    bmp.pixels.reserve(bmp.height*bmp.width);
    for(int yy=0;yy<bmp.height;++yy)
    {
        UC* p = data+scanlinesize*yy;
        for (int xx=0;xx<bmp.width;++xx)
        {
            RGB rgb;
            rgb.b = *p++;
            rgb.g = *p++;
            rgb.r = *p++;
            bmp.pixels.push_back(rgb);
        }
    }
    delete[] data;
}