64,637
社区成员
发帖
与我相关
我的任务
分享
HBITMAP hBitmap=NULL;
/*
if(::OpenClipboard(m_hWnd) && ::IsClipboardFormatAvailable(CF_BITMAP)){
hBitmap=(HBITMAP)::GetClipboardData(CF_BITMAP);
if(!hBitmap)return;
::CloseClipboard();
}
*/
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
hBitmap=bitmap;
BITMAP bm={0};
GetObject(hBitmap,sizeof(bm),(void**)&bm);
BITMAPINFOHEADER bih={0};
bih.biSize=sizeof(BITMAPINFOHEADER);
bih.biWidth=bm.bmWidth;
bih.biHeight=-bm.bmHeight;
bih.biPlanes=bm.bmPlanes;
bih.biBitCount=8;
bih.biCompression=BI_RGB;
if(bih.biWidth==0 || bih.biHeight==0){
AfxMessageBox("HBITMAP无效");
return;
}
int nColors=0;
DWORD cbPalette=0;
PALETTEENTRY *lpPaletteEnry=NULL;
HDC hDC=GetDC()->GetSafeHdc();
HPALETTE hPalette=NULL,hOldPalette=NULL;
//BYTE *biData=(BYTE*)malloc(abs(bih.biHeight)*bih.biWidth*sizeof(BYTE));
if(bih.biBitCount<=8){
nColors=1<<bih.biBitCount;
cbPalette=nColors*sizeof(PALETTEENTRY);//调色板的大小
LOGPALETTE lgPalette={0};
lgPalette.palVersion=0x300;
lgPalette.palNumEntries=nColors;
//创建调色板
hPalette=::CreatePalette(&lgPalette);
lpPaletteEnry=new PALETTEENTRY[nColors];
memset(lpPaletteEnry,0,sizeof(PALETTEENTRY)*nColors);
//扫描位图获得颜色表
HDC hMemoDC=::CreateCompatibleDC(NULL);
HBITMAP hOldBitmap=(HBITMAP)SelectObject(hMemoDC,hBitmap);
BYTE r,g,b;
BOOL bExists;COLORREF clr=0;int nPos=0;
ULONG *lpTemp=new ULONG[nColors],*lp;
memset(lpTemp,0,sizeof(ULONG)*nColors);
int index=0;
for(int y=0;y<bm.bmHeight;y++){
for(int x=0;x<bm.bmWidth;x++){
clr=GetPixel(hMemoDC,y,x);
r=GetRValue(clr);
g=GetGValue(clr);
b=GetBValue(clr);
index=0;
bExists=FALSE;
lp=lpTemp;
while(*lp && (nPos<nColors) ){
if(*(lp++)==clr){
bExists=TRUE;
break;
}else{
index++;
}
}
if(!bExists && nPos<nColors){
*lp=clr;
lpPaletteEnry[nPos].peRed=r;
lpPaletteEnry[nPos].peGreen=g;
lpPaletteEnry[nPos].peBlue=b;
nPos++;
}
//*(biData+(bm.bmHeight-y-1)*bm.bmWidth+x)=index;//上下对调,效果与GetDIBis相同
}
}
::SelectObject(hMemoDC,hOldBitmap);
::DeleteDC(hMemoDC);
//获取颜色表结束
::SetPaletteEntries(hPalette,0,nColors,lpPaletteEnry);//设置调色板的颜色表
hOldPalette=::SelectPalette(hDC,hPalette,FALSE);//选入设备
::RealizePalette(hDC);//实现调色板
}
DWORD cbClrData=(bm.bmWidth*bih.biBitCount+31)/8/4*4*bm.bmHeight;
DWORD cbData=sizeof(BITMAPINFOHEADER)+cbPalette+cbClrData;
BYTE *lpbi=new BYTE[cbData];
memset(lpbi,0,cbData);
bih.biSizeImage=cbClrData;
*((BITMAPINFOHEADER*)lpbi)=bih;
UINT iFlag=DIB_PAL_COLORS;
if(bih.biBitCount<=8){
iFlag=DIB_PAL_COLORS;
}
int lines=::GetDIBits(hDC,hBitmap,0,bm.bmHeight,lpbi+sizeof(BITMAPINFOHEADER)+cbPalette,(BITMAPINFO*)lpbi,iFlag);
if(lines!=bm.bmHeight){
AfxMessageBox("获取图像位失败");
return;
}
if(bih.biBitCount<=8){
//GetDIBits会对调色板区域进行乱填充数据
memcpy(lpbi+sizeof(BITMAPINFOHEADER),lpPaletteEnry,cbPalette);
}
if(hOldPalette){
::SelectPalette(hDC,hOldPalette,TRUE);
::DeleteObject(hPalette);
}
BITMAPFILEHEADER bfh={0};
bfh.bfType='MB';
bfh.bfSize=sizeof(BITMAPFILEHEADER)+cbData;
bfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+cbPalette;
CFile file;
if(!file.Open("bitmap.bmp",CFile::modeWrite|CFile::modeCreate)){
AfxMessageBox("创建文件失败");
return;
}
file.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));
file.SeekToEnd();
file.WriteHuge(lpbi,cbData);
file.Flush();
file.Close();