将24位真彩色转换为256色的bmp图像的问题 如题,如何通过程序将位图转换为256色。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 BOOL WINAPI TruecolorTo256(LPSTR lpDIB, LONG lWidth, LONG lHeight) { LONG i; LONG j; LPSTR lpDIBBits; LPSTR lpTemplateDIBBits; BYTE * lpSrc; BYTE * lpDst; //ͼÏñÿÐеÄ×Ö½ÚÊý LONG lSrcLineBytes; LONG lDstLineBytes; //Ö¸ÏòDIBµÄÖ¸Õë LPSTR lpTemplateDIB; HLOCAL hTemplateDIB; //Ö¸ÏòBITMAPINFOHEADERµÄÖ¸Õë LPBITMAPINFOHEADER lpBIH; //Ö¸ÏòBITMAPINFOµÄÖ¸Õë LPBITMAPINFO lpBI; //¼ÆËãת»»Ç°DIB³¤¶È DWORD dwSrcDIBSize = sizeof(BITMAPINFOHEADER) + lWidth * lHeight * 3; //¼ÆËãת»»ºóDIB³¤¶È DWORD dwDesDIBSize = sizeof(BITMAPINFOHEADER) + 4 * 256 + lWidth * lHeight; //ΪDIB·ÖÅäÄÚ´æ hTemplateDIB = GlobalAlloc(LHND, dwDesDIBSize * 8); if( hTemplateDIB == NULL) { //ÄÚ´æ·ÖÅäʧ°Ü£¬·µ»ØFALSE return FALSE; } //Ëø¶¨ÄÚ´æ lpTemplateDIB = (LPSTR) ::GlobalLock((HGLOBAL) hTemplateDIB); //¼ÆËãͼÏñÿÐеÄ×Ö½ÚÊý lSrcLineBytes = WIDTHBYTES(lWidth * 8 * 3); lDstLineBytes = WIDTHBYTES(lWidth * 8); //¸³³õÖµ memcpy(lpTemplateDIB, lpDIB, sizeof(BITMAPINFOHEADER)); lpBIH = (LPBITMAPINFOHEADER) lpTemplateDIB; lpBI = (LPBITMAPINFO) lpTemplateDIB; lpBIH->biBitCount = 8; //ÕÒµ½DIBͼÏñµÄÏñËØÆðʼλÖà lpDIBBits = ::FindDIBBits(lpDIB); lpTemplateDIBBits = ::FindDIBBits(lpTemplateDIB); for(i = 0; i < 256; i++) { lpBI->bmiColors[i].rgbRed = (BYTE)i; lpBI->bmiColors[i].rgbGreen = (BYTE)i; lpBI->bmiColors[i].rgbBlue = (BYTE)i; lpBI->bmiColors[i].rgbReserved = 0x00; } for(i = 0; i < lHeight; i++) { for(j = 0; j < lWidth; j++) { //Ö¸ÏòԭͼÏñºÍÄ¿µÄͼÏñµÄµÚiÐУ¬µÚj¸öÏñËصÄÖ¸Õë lpSrc = (unsigned char *)lpDIBBits + lSrcLineBytes * i + j * 3; lpDst = (unsigned char *)lpTemplateDIBBits + lDstLineBytes * i + j; //¸øת»»ºóµÄͼÏñÏñËظ³Öµ *lpDst = (BYTE)(0.299 * (*lpSrc) + 0.587 * (*(lpSrc+1)) + 0.114 * (*(lpSrc+2))); } } memset(lpDIB, 0, dwSrcDIBSize); memcpy(lpDIB, lpTemplateDIB, dwDesDIBSize); //ÊÍ·ÅÄÚ´æ GlobalUnlock(hTemplateDIB); GlobalFree(hTemplateDIB); return TRUE; } 这个以前别人问过~~ http://www.lihuasoft.net/article/show.php?id=3013http://community.csdn.net/Expert/topic/4904/4904566.xml?temp=.357815 http://www-scf.usc.edu/~flv/ipbook/chap05.htm这个是真彩色转256的他用的是最小平方误差来取近似颜色//其余的颜色依据最小平方误差近似为前256中最接近的一种 if (PalCounts > 256){ for (i = 256; i < PalCounts; i++){ //ColorError1记录最小平方误差,一开始赋一个很大的值 ColorError1=1000000000;//由12位索引值得到R,G,B的最高4位值 Blue = (long)((ColorIndex[i] & 0xf00) >> 4); Green = (long)((ColorIndex[i] & 0x0f0)); Red = (long)((ColorIndex[i] & 0x00f) << 4); ClrIndex = 0; for (j = 0; j < 256; j++){ //ColorError2计算当前的平方误差 ColorError2=(long)(Blue-pPal->palPalEntry[j].peBlue)*(Blue-pPal->palPalEntry[j].peBlue)+ (long)(Green-pPal->palPalEntry[j].peGreen)*(Green-pPal->palPalEntry[j].peGreen)+ (long)(Red-pPal->palPalEntry[j].peRed)*(Red-pPal->palPalEntry[j].peRed); if (ColorError2 < ColorError1){ //找到更小的了 ColorError1 = ColorError2; ClrIndex = j; //记录对应的调色板的索引值 } } MFC对话框程序: 直接关掉对话框后 资源没法释放的问题 内存DC描画的问题 有关于makefile的问题,在线急求 CDaoRecordset的1个简单问题 首次登陆,菜鸟问题:对于CListCtrl控件,怎样将某一item的选中状态取消啊?用什么函数啊?请不吝赐教,谢谢! 如何扩展IE,让他显示我的3D文件中的图像 关于屏幕保护程序! 菜鸟问题:关于dialog的 怎么把 ActiveX 代表控件大小的矩形边框去掉? 求使用CreateDIBSection显示8位灰度图的例子(不用那种多通道转单通道) 请问SOCKET接收数据处理的方式 如何正常退出监听UDP数据的线程?
{
LONG i;
LONG j;
LPSTR lpDIBBits;
LPSTR lpTemplateDIBBits;
BYTE * lpSrc;
BYTE * lpDst;
//ͼÏñÿÐеÄ×Ö½ÚÊý
LONG lSrcLineBytes;
LONG lDstLineBytes;
//Ö¸ÏòDIBµÄÖ¸Õë
LPSTR lpTemplateDIB;
HLOCAL hTemplateDIB;
//Ö¸ÏòBITMAPINFOHEADERµÄÖ¸Õë
LPBITMAPINFOHEADER lpBIH;
//Ö¸ÏòBITMAPINFOµÄÖ¸Õë
LPBITMAPINFO lpBI;
//¼ÆËãת»»Ç°DIB³¤¶È
DWORD dwSrcDIBSize = sizeof(BITMAPINFOHEADER) + lWidth * lHeight * 3;
//¼ÆËãת»»ºóDIB³¤¶È
DWORD dwDesDIBSize = sizeof(BITMAPINFOHEADER) + 4 * 256
+ lWidth * lHeight;
//ΪDIB·ÖÅäÄÚ´æ
hTemplateDIB = GlobalAlloc(LHND, dwDesDIBSize * 8);
if( hTemplateDIB == NULL)
{
//ÄÚ´æ·ÖÅäʧ°Ü£¬·µ»ØFALSE
return FALSE;
}
//Ëø¶¨ÄÚ´æ
lpTemplateDIB = (LPSTR) ::GlobalLock((HGLOBAL) hTemplateDIB);
//¼ÆËãͼÏñÿÐеÄ×Ö½ÚÊý
lSrcLineBytes = WIDTHBYTES(lWidth * 8 * 3);
lDstLineBytes = WIDTHBYTES(lWidth * 8);
//¸³³õÖµ
memcpy(lpTemplateDIB, lpDIB, sizeof(BITMAPINFOHEADER));
lpBIH = (LPBITMAPINFOHEADER) lpTemplateDIB;
lpBI = (LPBITMAPINFO) lpTemplateDIB;
lpBIH->biBitCount = 8;
//ÕÒµ½DIBͼÏñµÄÏñËØÆðʼλÖÃ
lpDIBBits = ::FindDIBBits(lpDIB);
lpTemplateDIBBits = ::FindDIBBits(lpTemplateDIB);
for(i = 0; i < 256; i++)
{
lpBI->bmiColors[i].rgbRed = (BYTE)i;
lpBI->bmiColors[i].rgbGreen = (BYTE)i;
lpBI->bmiColors[i].rgbBlue = (BYTE)i;
lpBI->bmiColors[i].rgbReserved = 0x00;
}
for(i = 0; i < lHeight; i++)
{
for(j = 0; j < lWidth; j++)
{
//Ö¸ÏòԭͼÏñºÍÄ¿µÄͼÏñµÄµÚiÐУ¬µÚj¸öÏñËصÄÖ¸Õë
lpSrc = (unsigned char *)lpDIBBits + lSrcLineBytes * i + j * 3;
lpDst = (unsigned char *)lpTemplateDIBBits + lDstLineBytes * i + j;
//¸øת»»ºóµÄͼÏñÏñËظ³Öµ
*lpDst = (BYTE)(0.299 * (*lpSrc) + 0.587 * (*(lpSrc+1))
+ 0.114 * (*(lpSrc+2)));
}
}
memset(lpDIB, 0, dwSrcDIBSize);
memcpy(lpDIB, lpTemplateDIB, dwDesDIBSize);
//ÊÍ·ÅÄÚ´æ
GlobalUnlock(hTemplateDIB);
GlobalFree(hTemplateDIB);
return TRUE;
}
这个以前别人问过~~
这个是真彩色转256的
他用的是最小平方误差来取近似颜色
//其余的颜色依据最小平方误差近似为前256中最接近的一种 if (PalCounts > 256){ for (i = 256; i < PalCounts; i++){ //ColorError1记录最小平方误差,一开始赋一个很大的值 ColorError1=1000000000;//由12位索引值得到R,G,B的最高4位值 Blue = (long)((ColorIndex[i] & 0xf00) >> 4); Green = (long)((ColorIndex[i] & 0x0f0)); Red = (long)((ColorIndex[i] & 0x00f) << 4); ClrIndex = 0; for (j = 0; j < 256; j++){ //ColorError2计算当前的平方误差 ColorError2=(long)(Blue-pPal->palPalEntry[j].peBlue)*(Blue-pPal->palPalEntry[j].peBlue)+ (long)(Green-pPal->palPalEntry[j].peGreen)*(Green-pPal->palPalEntry[j].peGreen)+ (long)(Red-pPal->palPalEntry[j].peRed)*(Red-pPal->palPalEntry[j].peRed); if (ColorError2 < ColorError1){ //找到更小的了 ColorError1 = ColorError2; ClrIndex = j; //记录对应的调色板的索引值 } }