在较大的 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];
从 PI
和 NPI
的填写方式来看,它们似乎是 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 文件的主要内容,如果未能解决你的问题,请参考以下文章