在较大的 bmp 文件中查找较小的 bmp 文件

Posted

技术标签:

【中文标题】在较大的 bmp 文件中查找较小的 bmp 文件【英文标题】:Finding a small bmp file in a bigger bmp file 【发布时间】:2014-07-19 17:28:13 【问题描述】:

我想从另一个较大的 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;

       

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

         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];

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

【问题讨论】:

让我们从最明显的开始;扫描线大小在 BMP 中填充 4 字节 你可以看看***.com/questions/24095738/… 虽然这可能是有效的 C++,但它有很重的 C 气味,唯一使用的 C++ 功能是 new 关键字,这使得它无法被标记为 C。但是,当我看到这样的代码:NPI = new unsigned int**[SCREEN_WIDTH];我想尽快逃跑...请看看现代 C++ 设计并使用标准库容器。 我想我几乎找到了问题,认为问题在于文件的读取,当代码进入第二行时(当第一行完全正确时)数据不匹配。也使用了 4 位,但它不起作用,帮助读取文件部分? 再次,正如我在我的帖子中所述,我删除了该帖子,因为您提到无法更改您的代码。您正在将 24 位位图读取为 32 位位图。您需要处理 4 字节的填充。 【参考方案1】:
PI[qq][kk][0] = data[kk * width + qq];

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

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

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

【讨论】:

我不小心删除了那部分询问另一个人,编辑它+添加了定义代码【参考方案2】:

让你开始吧。这是一个更好的 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;

【讨论】:

以上是关于在较大的 bmp 文件中查找较小的 bmp 文件的主要内容,如果未能解决你的问题,请参考以下文章

C++:.bmp 到文件中的字节数组

为工具栏图像条创建 32bpp BMP 文件?

在另一个声音文件中查找一个声音文件

16位bmp文件中RGB555转RGB565算法

怎么把一个较大的TXT文件分成几个较小的

滤出轮廓中较大或者较小的