32位位图转换24位位图
想自己实现大漠一样的找字、找图功能,用MFC CDC截图看了几张都是32位 色深,
查找颜色方式根本不一样。
没办法只能自己想办法把32位转换成24位查找RGB,上图片看看用:
0就是字的颜色;连接起来就是 CALL
直接上代码:
/*
功能:32位位图转换24
参数1:保存文件的路径
参数2:32位位图文件缓冲区
参数3:是否保存位图到文件
返回值:返回转换后的24位 位图缓冲区 可以直接
*/
char* Bmp32To24(const char* Filepath, const char* src,bool ret)
{
PBITMAPINFO BmpInfoHeader = (PBITMAPINFO)((UINT64)src + BMP_FILE_HEADER_LENGTH);
int N = 4 - ((BmpInfoHeader->bmiHeader.biWidth * 3) % 4);
BITMAPINFOHEADER bi = { 0 };
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = BmpInfoHeader->bmiHeader.biWidth;
bi.biHeight = BmpInfoHeader->bmiHeader.biHeight;
bi.biPlanes = 1;
bi.biBitCount = BMP_24_BIT;
bi.biCompression = 0;
bi.biSizeImage = ((BmpInfoHeader->bmiHeader.biWidth * 3) * BmpInfoHeader->bmiHeader.biHeight)+(N * BmpInfoHeader->bmiHeader.biHeight);
bi.biXPelsPerMeter = BmpInfoHeader->bmiHeader.biXPelsPerMeter;
bi.biYPelsPerMeter= BmpInfoHeader->bmiHeader.biYPelsPerMeter;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
PBITMAPFILEHEADER pbi = (PBITMAPFILEHEADER)src;
BITMAPFILEHEADER BiHeder = { 0 };
BiHeder.bfType = pbi->bfType;
BiHeder.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
int OffSize = BiHeder.bfSize;
BiHeder.bfOffBits = BiHeder.bfSize;
BiHeder.bfSize+= bi.biSizeImage+2;
BiHeder.bfReserved1 = pbi->bfReserved1;
BiHeder.bfReserved2 = pbi->bfReserved2;
char* bmp24 = new char[BiHeder.bfSize];
if (!bmp24)
{
return 0;
}
memset(bmp24, 0, BiHeder.bfSize);
memcpy(bmp24, &BiHeder, sizeof(BITMAPFILEHEADER));
memcpy(bmp24+ sizeof(BITMAPFILEHEADER), &bi, sizeof(BITMAPINFOHEADER));
int w = bi.biWidth, h = bi.biHeight;
int dx=0,dx1=0;
PCHAR p = (PCHAR)((DWORD64)bmp24 + OffSize);
PCHAR p1 = (PCHAR)((DWORD64)src+ OffSize);
for (size_t i = 0; i < h; i++)
{
for (size_t j = 0; j < w; j++)
{
if (j==(w-1))
{
memcpy(p+dx,p1+dx1,3);
dx += N+3; //必须是4的倍数所以指针往后移动3+N;
}
else
{
memcpy(p + dx, p1 + dx1, 3);
dx += 3;//每次取四个字中的前3个所以+3
}
dx1 += 4;//每次取四个字中的前3个第四个丢弃
}
}
if (ret)
{
FILE* fp = NULL;
fopen_s(&fp, Filepath, "wb+");
if (NULL == fp)
{
//FreeRes_ShowError("LockResource");
delete[] bmp24;
return FALSE;
}
fwrite(bmp24, sizeof(char), BiHeder.bfSize, fp);
fclose(fp);
}
return bmp24;
}
下面读取RGB每个颜色:
BOOL BMPExtractBGR(const char* strPath, LPVOID outdata)
{
HANDLE hFile = CreateFile(strPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD fileSize = GetFileSize(hFile, NULL); //获得文件大小的低两字节
char* pSrcData = new char[fileSize]; //创建缓冲区
DWORD realRead = 0;
BOOL ret = false;
ret = ReadFile(hFile, pSrcData, fileSize, &realRead, NULL); //拷贝文件的内容给缓冲区fileBuff
CloseHandle(hFile);
if (ret)
{
BITMAPINFO BmpInfoHeader;
//BITMAP fHeader;
if (isNull(pSrcData) || isNull(outdata))
{
delete[] pSrcData;
return FALSE;
}
//根据前两个字节,判断是不是BMP图片
if ((pSrcData[0] != 'B') || (pSrcData[1] != 'M'))
{
//printf("not a bmp picture.\n");
delete[] pSrcData;
return FALSE;
}
//获取信息头
memcpy(&BmpInfoHeader, pSrcData + BMP_FILE_HEADER_LENGTH, sizeof(BmpInfoHeader));
//将宽高信息传递出去
//int N = 4 - ((width * 3) % 4);
//判断BMP图片像素的位数
if (BmpInfoHeader.bmiHeader.biBitCount == BMP_24_BIT)
{
//offSet = (UINT64)fHeader.bmBits- (UINT64)pSrcData;//文件头到BGR数据的偏移量
//读取文件的BRG数据
//for (i = 0; i < height-1; i++)
//{
// LPVOID t_p = (LPVOID)((UINT64)fHeader.bmBits + ((width * 3 + N) * height));
// UINT64 t_p1 = (UINT64)t_p - ((i+1) * (width * 3 + N));
// if (t_p1-((UINT64)fHeader.bmBits)<0)
// {
// break;
// }
// memcpy(*pDstData + i * width * 3, (LPVOID)t_p1, width * 3);
//
//}
*(LPVOID*)outdata = pSrcData;
return TRUE;
}
else if (BmpInfoHeader.bmiHeader.biBitCount == BMP_32_BIT)
{
char* ctha= Bmp32To24(strPath,pSrcData);
//sizeof(BITMAPFILEHEADER)
if (pSrcData)
{
delete[] pSrcData;
}
*(LPVOID*)outdata = ctha;
if (!ctha)
{
return FALSE;
}
return TRUE;
}
}
if (pSrcData)
{
delete[] pSrcData;
}
return FALSE;
}
int height = 0;
int width = 0;
char* data=0;
LPVOID filedata= 0;
if (BMPExtractBGR("H:\\VS1\\FindPic\\res\\123.bmp", &filedata))
{
BITMAPINFO bmp;
BITMAPS fHeader;
memcpy(&bmp, (LPVOID)((UINT64)filedata+ BMP_FILE_HEADER_LENGTH), sizeof(BITMAPINFO));
memcpy(&fHeader, filedata , sizeof(BITMAPS));
width = bmp.bmiHeader.biWidth;
height = bmp.bmiHeader.biHeight;
int N = 4 - ((width * 3) % 4);
data = new char[width* height*3];
memset(data, 0, width * height*3);
int offSet = fHeader.Offbits;//文件头到BGR数据的偏移量
读取文件的BRG数据
for (int i = 0; i < height; i++)
{
LPVOID t_p = (LPVOID)((UINT64)filedata + offSet + ((width * 3 + N) * height));
UINT64 t_p1 = (UINT64)t_p - ((i+1) * (width * 3 + N));
memcpy(data + i * width * 3, (LPVOID)t_p1, width * 3);
}
{
CString str1, str2;
int R = 0, G = 0, B = 0;
for (size_t i = 0; i < height; i++)
{
for (size_t j = 0; j < width; j++)
{
if (j == 0)
{
int ch = 0;
// memcpy(&ch, data + i *j*3, 3);
SetBValue(ch, (int)*(char*)((DWORD64)data + (i * width * 3 + j * 3)));
SetGValue(ch, (int)*(char*)((DWORD64)data + (i * width * 3 + j * 3 + 1)));
SetRValue(ch, (int)*(char*)((DWORD64)data + (i * width * 3 + j * 3 + 2)));
//R = GetRValue(ch);//获取c中R的值
//G = GetGValue(ch);//获取c中R的值
//B = GetBValue(ch);//获取c中R的值
if (ch == 0)
{
str2 = " 0";
}
else
{
str2 = " 1";
}
str1 += str2;
continue;
}
int ch = 0;
// memcpy(&ch, data + i * j * 3, 3);
int ch2 = 0;
memcpy(&ch2, (int*)((DWORD64)data + (i * width * 3 + j * 3 + 2)), 1);
SetRValue(ch, ch2);
ch2 = 0;
memcpy(&ch2, (int*)((DWORD64)data + (i * width * 3 + j * 3 + 1)), 1);
SetGValue(ch, ch2);
ch2 = 0;
memcpy(&ch2, (int*)((DWORD64)data + (i * width * 3 + j * 3)), 1);
SetBValue(ch, ch2);
if (ch == 0)
{
str2 = " 0";
}
else
{
str2 = " 1";
}
str1 += str2;
}
str1 += "\r\n";
}
SetDlgItemText(EDIT1, str1);
}
}
delete[] filedata;
delete[] data;
}