真彩色位图(BMP)文件如何转换为256色位图?在线等待 我有一个真彩色位图文件(A.BMP),现在想把它转换成256色的位图文件(B.BMP),请问如何实现? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 1、mspaint打开,另存为256色bmp.2、HBITMAP LoadBitmap( HINSTANCE hInstance, // handle to application instance LPCTSTR lpBitmapName // address of bitmap resource name);BITMAPINFO * BitmapToDIB(HPALETTE hPal, // palette for color conversion HBITMAP hBmp, // DDB for convert int nBitCount, int nCompression) // format wanted{ typedef struct { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[256+3]; } DIBINFO; BITMAP ddbinfo; DIBINFO dibinfo; // retrieve DDB information if ( GetObject(hBmp, sizeof(BITMAP), & ddbinfo)==0 ) return NULL; // fill out BITMAPINFOHEADER based on size and required format memset(&dibinfo, 0, sizeof(dibinfo)); dibinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); dibinfo.bmiHeader.biWidth = ddbinfo.bmWidth; dibinfo.bmiHeader.biHeight = ddbinfo.bmHeight; dibinfo.bmiHeader.biPlanes = 1; dibinfo.bmiHeader.biBitCount = nBitCount; dibinfo.bmiHeader.biCompression = nCompression; HDC hDC = GetDC(NULL); // screen DC HGDIOBJ hpalOld; if ( hPal ) hpalOld = SelectPalette(hDC, hPal, FALSE); else hpalOld = NULL; // query GDI for image size GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, NULL, (BITMAPINFO *) & dibinfo, DIB_RGB_COLORS); int nInfoSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * GetDIBColorCount(dibinfo.bmiHeader); int nTotalSize = nInfoSize + GetDIBPixelSize(dibinfo.bmiHeader); BYTE * pDIB = new BYTE[nTotalSize]; if ( pDIB ) { memcpy(pDIB, & dibinfo, nInfoSize); if ( ddbinfo.bmHeight != GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, pDIB + nInfoSize, (BITMAPINFO *) pDIB, DIB_RGB_COLORS) ) { delete [] pDIB; pDIB = NULL; } } if ( hpalOld ) SelectObject(hDC, hpalOld); ReleaseDC(NULL, hDC); return (BITMAPINFO *) pDIB;}BOOL SaveDIBToBmp(const char* pFileName, const BITMAPINFO *pBMI, const BYTE *pBits){ if(pFileName==NULL){ return FALSE; } HANDLE handle = CreateFile(pFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(handle == INVALID_HANDLE_VALUE){ return FALSE; } BITMAPFILEHEADER bmFH; int nHeadSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * GetDIBColorCount(pBMI->bmiHeader); bmFH.bfType = 0x4D42; bmFH.bfSize = nHeadSize + GetDIBPixelSize(pBMI->bmiHeader); bmFH.bfReserved1 = 0; bmFH.bfReserved2 = 0; bmFH.bfOffBits = nHeadSize + sizeof(BITMAPFILEHEADER); DWORD dwRead = 0; WriteFile(handle, & bmFH, sizeof(bmFH), & dwRead, NULL); if(pBits==NULL) // packed DIB pBits = (BYTE *) pBMI + nHeadSize; WriteFile(handle, pBMI, nHeadSize, & dwRead, NULL); WriteFile(handle, pBits, GetDIBPixelSize(pBMI->bmiHeader), & dwRead, NULL); CloseHandle(handle); return TRUE;}给下面函数nBitCount 传递8表示保存为256色位图BITMAPINFO * BitmapToDIB(HPALETTE hPal, // palette for color conversion HBITMAP hBmp, // DDB for convert int nBitCount, int nCompression) // format wanted 谢谢oldworm(oldworm),我试过OK后,马上给分! oldworm(oldworm),编译后有以下三个错误:error C2065: 'GetDIBColorCount' : undeclared identifiererror C2065: 'GetDIBPixelSize' : undeclared identifiererror C2660: 'ReleaseDC' : function does not take 2 parameters何解? romanticist(让我拥抱你入梦),为什么在MSDN里找不到?是用户自己定义的吗? int GetDIBPixelSize(const BITMAPINFOHEADER & bmih){ if ( bmih.biSizeImage ) return bmih.biSizeImage; else return ( bmih.biWidth * bmih.biBitCount + 31 ) / 32 * 4 * bmih.biPlanes * abs(bmih.biHeight);}int GetDIBColorCount(const BITMAPINFOHEADER & bmih){ if ( bmih.biBitCount <= 8 ) if ( bmih.biClrUsed ) return bmih.biClrUsed; else return 1 << bmih.biBitCount; else if ( bmih.biCompression==BI_BITFIELDS ) return 3 + bmih.biClrUsed; else return bmih.biClrUsed;}Release修改为:::ReleaseDC你是不是将代码拆开了拿到你的程序中调用的? oldworm(oldworm):是啊!我再试试看,谢谢!! http://www.enwww.net/mysoftware/64kbmp2gray.zip借花 谢谢rujor(rujor),但是运行不是很理想。 oldworm(oldworm),我还没有试出来,或者你告诉我如何调用你的那些函数吧。我现在有一幅图(C:\A.bmp),它是真彩格式,怎么变成256色的图(C:\B.bmp)? 楼主要的是灰度图吗?是的话,rujor(rujor)的可以,不过他的是16位的,还有处理24位的,实际上只是把真彩图的每个象素的R,G,B三色用(r*0.29900 + g*0.58700 + b*0.11400)转一下换成在256色表中的索引。如果是降色的话,算法比较繁了。 paul2002():不是灰度图图,你有24位转为8位的例程吗?oldworm(oldworm):还是不行啊!? 谢谢各位!我已经在以下网址找到正确的方法,不敢独享:http://msdn.microsoft.com/code/default.asp?url=/msdn-files/026/000/209/Source%20Files/AOTBLOBDlg_cpp.asp当然,分数还是照给不误!谢谢捧场!!! 让对话框响应鼠标单双击 请教:类似蒙恬手写的软件是怎么实现的。只要软件运行着,可以将文字写入到其他任何字处理软件工作区中 老板要我交货啊,高手帮一把吧。ACCESS中SQL语句变量的使用格式: ATL控件的事件获取? VC菜鸟求救~VC安装后编译有问题~在线等待!! 哪位大虾能送我一个GetMessage的钩子程序呀! 怎么给按钮改名? 请问如何低格昆腾6G的硬盘? 求VC画球的程序代码 ATL控件的Release版本无法捕获异常?? 关于《VC技术内幕》(潘爱民译)第15章的一个问题 急救啊,一解决马上给分
2、HBITMAP LoadBitmap(
HINSTANCE hInstance, // handle to application instance
LPCTSTR lpBitmapName // address of bitmap resource name
);BITMAPINFO * BitmapToDIB(HPALETTE hPal, // palette for color conversion
HBITMAP hBmp, // DDB for convert
int nBitCount, int nCompression) // format wanted
{
typedef struct
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256+3];
} DIBINFO; BITMAP ddbinfo;
DIBINFO dibinfo; // retrieve DDB information
if ( GetObject(hBmp, sizeof(BITMAP), & ddbinfo)==0 )
return NULL; // fill out BITMAPINFOHEADER based on size and required format
memset(&dibinfo, 0, sizeof(dibinfo)); dibinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
dibinfo.bmiHeader.biWidth = ddbinfo.bmWidth;
dibinfo.bmiHeader.biHeight = ddbinfo.bmHeight;
dibinfo.bmiHeader.biPlanes = 1;
dibinfo.bmiHeader.biBitCount = nBitCount;
dibinfo.bmiHeader.biCompression = nCompression; HDC hDC = GetDC(NULL); // screen DC
HGDIOBJ hpalOld;
if ( hPal )
hpalOld = SelectPalette(hDC, hPal, FALSE);
else
hpalOld = NULL; // query GDI for image size
GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, NULL, (BITMAPINFO *) & dibinfo, DIB_RGB_COLORS); int nInfoSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * GetDIBColorCount(dibinfo.bmiHeader);
int nTotalSize = nInfoSize + GetDIBPixelSize(dibinfo.bmiHeader); BYTE * pDIB = new BYTE[nTotalSize]; if ( pDIB )
{
memcpy(pDIB, & dibinfo, nInfoSize);
if ( ddbinfo.bmHeight != GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, pDIB + nInfoSize, (BITMAPINFO *) pDIB, DIB_RGB_COLORS) )
{
delete [] pDIB;
pDIB = NULL;
}
} if ( hpalOld )
SelectObject(hDC, hpalOld); ReleaseDC(NULL, hDC); return (BITMAPINFO *) pDIB;
}BOOL SaveDIBToBmp(const char* pFileName, const BITMAPINFO *pBMI, const BYTE *pBits)
{
if(pFileName==NULL){
return FALSE;
} HANDLE handle = CreateFile(pFileName, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(handle == INVALID_HANDLE_VALUE){
return FALSE;
} BITMAPFILEHEADER bmFH; int nHeadSize = sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * GetDIBColorCount(pBMI->bmiHeader); bmFH.bfType = 0x4D42;
bmFH.bfSize = nHeadSize + GetDIBPixelSize(pBMI->bmiHeader);
bmFH.bfReserved1 = 0;
bmFH.bfReserved2 = 0;
bmFH.bfOffBits = nHeadSize + sizeof(BITMAPFILEHEADER); DWORD dwRead = 0;
WriteFile(handle, & bmFH, sizeof(bmFH), & dwRead, NULL); if(pBits==NULL) // packed DIB
pBits = (BYTE *) pBMI + nHeadSize;
WriteFile(handle, pBMI, nHeadSize, & dwRead, NULL);
WriteFile(handle, pBits, GetDIBPixelSize(pBMI->bmiHeader), & dwRead, NULL); CloseHandle(handle); return TRUE;
}给下面函数nBitCount 传递8表示保存为256色位图
BITMAPINFO * BitmapToDIB(HPALETTE hPal, // palette for color conversion
HBITMAP hBmp, // DDB for convert
int nBitCount, int nCompression) // format wanted
error C2065: 'GetDIBPixelSize' : undeclared identifier
error C2660: 'ReleaseDC' : function does not take 2 parameters何解?
{
if ( bmih.biSizeImage )
return bmih.biSizeImage;
else
return ( bmih.biWidth * bmih.biBitCount + 31 ) / 32 * 4 * bmih.biPlanes * abs(bmih.biHeight);
}int GetDIBColorCount(const BITMAPINFOHEADER & bmih)
{
if ( bmih.biBitCount <= 8 )
if ( bmih.biClrUsed )
return bmih.biClrUsed;
else
return 1 << bmih.biBitCount;
else if ( bmih.biCompression==BI_BITFIELDS )
return 3 + bmih.biClrUsed;
else
return bmih.biClrUsed;
}Release修改为:
::ReleaseDC你是不是将代码拆开了拿到你的程序中调用的?
借花
我现在有一幅图(C:\A.bmp),它是真彩格式,怎么变成256色的图(C:\B.bmp)?
如果是降色的话,算法比较繁了。
当然,分数还是照给不误!谢谢捧场!!!