32位位图转换24位位图

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;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
将24位位转换成8位位的过程中,需要用到调色板。调色板是一个包含256种颜色的表格,每个颜色都由三个8位组成的RGB值来表示。具体的转换步骤如下: 1. 创建一个空白的8位位,并设置它的宽度和高度与原始24位位相同。 2. 创建一个调色板,其中包含256种颜色。可以使用ColorPalette类来创建调色板。 3. 遍历原始24位位的每个像素,将它的RGB值转换成一个0到255之间的整数,然后将该整数作为调色板中对应颜色的索引,将索引值写入新的8位位中。 4. 将调色板与新的8位位相关联,使用Bitmap类的SetPixel和GetPixel方法可以完成这一步操作。 5. 最后保存新的8位位即可。 下面是一个C#代码示例,可以将24位位转换成8位位: ```csharp public static Bitmap ConvertTo8bpp(Bitmap bmp) { // 创建一个新的8位位 Bitmap newBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format8bppIndexed); // 创建调色板 ColorPalette pal = newBmp.Palette; for (int i = 0; i < 256; i++) { pal.Entries[i] = Color.FromArgb(i, i, i); } newBmp.Palette = pal; // 遍历原始位的每个像素,并将RGB值转换成索引 for (int y = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++) { Color color = bmp.GetPixel(x, y); int index = (int)(0.299 * color.R + 0.587 * color.G + 0.114 * color.B); newBmp.SetPixel(x, y, Color.FromArgb(index, index, index)); } } return newBmp; } ``` 在这个示例中,使用了YUV颜色空间的转换公式将RGB值转换成了索引。可以根据具体需求使用不同的转换公式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C+V代码搬运工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值