分享
 
 
 

编程技巧15法之三

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

1. 如何替换HBITMAP中的颜色值

#define COLORREF2RGB(Color) (Color & 0xff00) | ((Color >> 16) & 0xff)

| ((Color << 16) & 0xff0000)

HBITMAP ReplaceColor (HBITMAP hBmp,COLORREF cOldColor,COLORREF cNewColor)

{

HBITMAP RetBmp=NULL;

if (hBmp)

{

HDC BufferDC=CreateCompatibleDC(NULL); // 源位图DC

if (BufferDC)

{

SelectObject(BufferDC,hBmp); // 选入DC中

HDC DirectDC=CreateCompatibleDC(NULL); // 目标DC

if (DirectDC)

{

// 获取源位图大小

BITMAP bm;

GetObject(hBmp, sizeof(bm), &bm);

// 初始化BITMAPINFO信息,以便使用CreateDIBSection

BITMAPINFO RGB32BitsBITMAPINFO;

ZeroMemory(&RGB32BitsBITMAPINFO,sizeof(BITMAPINFO));

RGB32BitsBITMAPINFO.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

RGB32BitsBITMAPINFO.bmiHeader.biWidth=bm.bmWidth;

RGB32BitsBITMAPINFO.bmiHeader.biHeight=bm.bmHeight;

RGB32BitsBITMAPINFO.bmiHeader.biPlanes=1;

RGB32BitsBITMAPINFO.bmiHeader.biBitCount=32;

UINT * ptPixels;

HBITMAP DirectBitmap= CreateDIBSection(DirectDC,

(BITMAPINFO *)&RGB32BitsBITMAPINFO,

DIB_RGB_COLORS,(void **)&ptPixels, NULL, 0);

if (DirectBitmap)

{

HGDIOBJ PreviousObject=SelectObject(DirectDC, DirectBitmap);

BitBlt(DirectDC,0,0,bm.bmWidth,bm.bmHeight,BufferDC,0,0,SRCCOPY);

// 转换 COLORREF 为 RGB

cOldColor=COLORREF2RGB(cOldColor);

cNewColor=COLORREF2RGB(cNewColor);

// 替换颜色

for (int i=((bm.bmWidth*bm.bmHeight)-1);i>=0;i--)

{

if (ptPixels[i]==cOldColor) ptPixels[i]=cNewColor;

}

// 修改位图 DirectBitmap

SelectObject(DirectDC,PreviousObject);

// 完成

RetBmp=DirectBitmap;

}

// 释放DC

DeleteDC(DirectDC);

}

// 释放DC

DeleteDC(BufferDC);

}

}

return RetBmp;

}

用法:

HBITMAP hBmp2 = LoadBitmap(g_hinstance,MAKEINTRESOURCE(IDB_SAMPLEBITMAP));

HBITMAP hBmp = ReplaceColor(hBmp2,0xff0000,0x00ff00); // 替换蓝色为绿色

......

DeleteObject(hBmp2);

DeleteObject(hBmp);

2. 如何转换并保存位图

//********************************************************************************

//* 名称:DDBToDIB

//* 作者:徐景周(jingzhou_xu@163.net)

//* 功能:设备相关转换为设备无关位图

//********************************************************************************

HANDLE CScreenSnapDlg::DDBToDIB( CBitmap& bitmap, DWORD dwCompression /* = BI_RGB */)

{

BITMAP bm;

BITMAPINFOHEADER bi;

LPBITMAPINFOHEADER lpbi;

DWORD dwLen;

HANDLE hDIB;

HANDLE handle;

HDC hDC;

HPALETTE hPal;

CWindowDC dc( this );

CPalette pal;

//如果支持调色板的话,则建立它

if( dc.GetDeviceCaps( RASTERCAPS ) & RC_PALETTE )

{

UINT nSize = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * 256 );

LOGPALETTE* pLP = (LOGPALETTE*)new BYTE[nSize];

pLP->palVersion = 0x300;

pLP->palNumEntries = (unsigned short)GetSystemPaletteEntries( dc, 0, 255,

pLP->palPalEntry );

pal.CreatePalette( pLP );

//释放

delete[] pLP;

}

ASSERT( bitmap.GetSafeHandle() );

//不支持BI_BITFIELDS类型

if( dwCompression == BI_BITFIELDS )

return NULL;

//如果调色板为空,则用默认调色板

hPal = (HPALETTE) pal.GetSafeHandle();

if (hPal==NULL)

hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);

//获取位图信息

bitmap.GetObject(sizeof(bm),(LPSTR)&bm);

//初始化位图信息头

bi.biSize = sizeof(BITMAPINFOHEADER);

bi.biWidth = bm.bmWidth;

bi.biHeight = bm.bmHeight;

bi.biPlanes = 1;

bi.biBitCount = (unsigned short)(bm.bmPlanes * bm.bmBitsPixel) ;

bi.biCompression = dwCompression;

bi.biSizeImage = 0;

bi.biXPelsPerMeter = 0;

bi.biYPelsPerMeter = 0;

bi.biClrUsed = 0;

bi.biClrImportant = 0;

//计算信息头及颜色表大小

int nColors = 0;

if(bi.biBitCount <= 8)

{

nColors = (1 << bi.biBitCount);

}

dwLen = bi.biSize + nColors * sizeof(RGBQUAD);

hDC = ::GetDC(NULL);

hPal = SelectPalette(hDC,hPal,FALSE);

RealizePalette(hDC);

//为信息头及颜色表分配内存

hDIB = GlobalAlloc(GMEM_FIXED,dwLen);

if (!hDIB){

SelectPalette(hDC,hPal,FALSE);

::ReleaseDC(NULL,hDC);

return NULL;

}

lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);

*lpbi = bi;

//调用 GetDIBits 计算图像大小

GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,

(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);

bi = *lpbi;

//图像的每一行都对齐(32bit)边界

if (bi.biSizeImage == 0){

bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)

* bi.biHeight;

if (dwCompression != BI_RGB)

bi.biSizeImage = (bi.biSizeImage * 3) / 2;

}

//重新分配内存大小,以便放下所有数据

dwLen += bi.biSizeImage;

handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE) ;

if (handle != NULL)

hDIB = handle;

else

{

GlobalFree(hDIB);

//重选原始调色板

SelectPalette(hDC,hPal,FALSE);

::ReleaseDC(NULL,hDC);

return NULL;

}

//获取位图数据

lpbi = (LPBITMAPINFOHEADER)hDIB;

//最终获得的DIB

BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),

0L, //扫描行起始处

(DWORD)bi.biHeight, //扫描行数

(LPBYTE)lpbi //位图数据地址

+ (bi.biSize + nColors * sizeof(RGBQUAD)),

(LPBITMAPINFO)lpbi, //位图信息地址

(DWORD)DIB_RGB_COLORS); //颜色板使用RGB

if( !bGotBits )

{

GlobalFree(hDIB);

SelectPalette(hDC,hPal,FALSE);

::ReleaseDC(NULL,hDC);

return NULL;

}

SelectPalette(hDC,hPal,FALSE);

::ReleaseDC(NULL,hDC);

return hDIB;

}

//********************************************************************************

//* 名称:SaveBitmapToFile

//* 修改:徐景周(jingzhou_xu@163.net)

//* 功能:保存为位图文件

//********************************************************************************

BOOL CScreenSnapDlg::SaveBitmapToFile(HBITMAP hBitmap , CString lpFileName)

{

HDC hDC; //设备描述表

int iBits; //当前显示分辨率下每个像素所占字节数

WORD wBitCount; //位图中每个像素所占字节数

DWORD dwPaletteSize=0, //定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数

dwBmBitsSize,

dwDIBSize, dwWritten;

BITMAP Bitmap;

BITMAPFILEHEADER bmfHdr; //位图属性结构

BITMAPINFOHEADER bi; //位图文件头结构

LPBITMAPINFOHEADER lpbi; //位图信息头结构

HANDLE fh, hDib, hPal,hOldPal=NULL; //指向位图信息头结构,定义文件,分配内存句柄,调色板句柄

//计算位图文件每个像素所占字节数

hDC = CreateDC("DISPLAY",NULL,NULL,NULL);

iBits = GetDeviceCaps(hDC, BITSPIXEL) *

GetDeviceCaps(hDC, PLANES);

DeleteDC(hDC);

if (iBits <= 1)

wBitCount = 1;

else if (iBits <= 4)

wBitCount = 4;

else if (iBits <= 8)

wBitCount = 8;

else if (iBits <= 24)

wBitCount = 24;

//计算调色板大小

if (wBitCount <= 8)

dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);

//设置位图信息头结构

GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);

bi.biSize = sizeof(BITMAPINFOHEADER);

bi.biWidth = Bitmap.bmWidth;

bi.biHeight = Bitmap.bmHeight;

bi.biPlanes = 1;

bi.biBitCount = wBitCount;

bi.biCompression = BI_RGB;

bi.biSizeImage = 0;

bi.biXPelsPerMeter = 0;

bi.biYPelsPerMeter = 0;

bi.biClrUsed = 0;

bi.biClrImportant = 0;

dwBmBitsSize = ((Bitmap.bmWidth *

wBitCount+31)/32)* 4

*Bitmap.bmHeight ;

//为位图内容分配内存

hDib = GlobalAlloc(GHND,dwBmBitsSize+

dwPaletteSize+sizeof(BITMAPINFOHEADER));

lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);

*lpbi = bi;

// 处理调色板

hPal = GetStockObject(DEFAULT_PALETTE);

if (hPal)

{

hDC = ::GetDC(NULL);

hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);

RealizePalette(hDC);

}

// 获取该调色板下新的像素值

GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,

(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,

(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);

//恢复调色板

if (hOldPal)

{

SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);

RealizePalette(hDC);

::ReleaseDC(NULL, hDC);

}

//创建位图文件

fh = CreateFile(lpFileName, GENERIC_WRITE,

0, NULL, CREATE_ALWAYS,

FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

if (fh == INVALID_HANDLE_VALUE)

return FALSE;

// 设置位图文件头

bmfHdr.bfType = 0x4D42; // "BM"

dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;

bmfHdr.bfSize = dwDIBSize;

bmfHdr.bfReserved1 = 0;

bmfHdr.bfReserved2 = 0;

bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)

+ (DWORD)sizeof(BITMAPINFOHEADER)

+ dwPaletteSize;

// 写入位图文件头

WriteFile(fh, (LPSTR)&bmfHdr, sizeof

(BITMAPFILEHEADER), &dwWritten, NULL);

// 写入位图文件其余内容

WriteFile(fh, (LPSTR)lpbi, dwDIBSize,

&dwWritten, NULL);

//消除内存分配

GlobalUnlock(hDib);

GlobalFree(hDib);

CloseHandle(fh);

return TRUE;

}

联系方式:

地址:陕西省西安市劳动路2号院六单元

邮编:710082

作者EMAIL:jingzhou_xu@163.net

未来工作室(Future Studio)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有