将HBITMAP保存为文件

本文介绍了一种将Windows的HBITMAP对象转换为标准BMP文件的方法。通过使用GetDIBits和CreateDC等API函数,文章详细阐述了如何获取位图信息并将其保存到磁盘上。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

bool HBITMAPToBmp(HBITMAP hBitmap, const CString & strFileName

)

{

 

 

if(hBitmap == NULL

)

 

 

return false

;

 

 

HDC hDC

;

 

 

int iBits;

//当前分辨率下每象素所占字节数

 

 

WORD wBitCount;

//位图中每象素所占字节数

 

 

DWORD dwPaletteSize=0;

//定义调色板大小

 

 

DWORD dwBmBitsSize=0;

//位图中像素字节大小

 

 

DWORD dwDIBSize=0;

//位图文件大小

 

 

DWORD dwWritten=0;

//位图文件大小 写入文件字节数

 

 

BITMAP Bitmap;

//位图属性结构

 

 

BITMAPFILEHEADER bmfHdr;

//位图文件头结构

 

 

BITMAPINFOHEADER bi;

//位图信息头结构

 

 

LPBITMAPINFOHEADER lpbi = NULL;

//指向位图信息头结构

 

 

HANDLE hDib, hPal, hOldPal = NULL;

//定义文件,分配内存句柄,调色板句柄

 

 

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

 

 

hDC = CreateDC(_T("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

 

 

wBitCount

= 24;

 

 

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

);

 

 

bi.biSize = sizeof(BITMAPINFOHEADER

);

 

 

bi.biWidth = Bitmap.bmWidth

;

 

 

bi.biHeight = Bitmap.bmHeight

;

 

 

if(Bitmap.bmWidth < 100 || Bitmap.bmHeight

< 100)

 

 

return false

;

 

 

bi.biPlanes

= 1;

 

 

bi.biBitCount = wBitCount

;

 

 

bi.biCompression = BI_RGB

;

 

 

bi.biSizeImage

= 0;

 

 

bi.biXPelsPerMeter

= 0;

 

 

bi.biYPelsPerMeter

= 0;

 

 

bi.biClrImportant

= 0;

 

 

bi.biClrUsed

= 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

);

}

 

 

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

 

 

int nRet = GetDIBits(hDC

,

 

 

hBitmap

,

0,

(

 

UINT)Bitmap.bmHeight

,

(

 

LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize

,

(

 

BITMAPINFO *)lpbi

,

 

 

DIB_RGB_COLORS

);

 

 

if (0 == nRet

)

{

 

 

nRet

= 0;

}

 

 

//恢复调色板

 

 

if(hOldPal

)

{

::

 

SelectPalette(hDC, (HPALETTE)hOldPal,TRUE

);

 

 

RealizePalette(hDC

);

::

 

ReleaseDC(NULL,hDC

);

}

 

 

//设置位图文件头

 

 

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

;

 

 

//创建位图文件

 

 

HANDLE fh = CreateFile(strFileName.operator LPCTSTR(), GENERIC_WRITE,0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL

);

 

 

if (fh == INVALID_HANDLE_VALUE

)

{

 

 

int x = GetLastError

();

 

 

GlobalUnlock(hDib

);

 

 

GlobalFree(hDib

);

 

 

return FALSE

;

}

 

 

//写入位图文件头

 

 

WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten,NULL

);

 

 

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

 

 

WriteFile(fh, (LPSTR)lpbi, dwDIBSize - sizeof(BITMAPFILEHEADER), &dwWritten, NULL

);

 

 

//清除

 

 

CloseHandle(fh

);

 

 

GlobalUnlock(hDib

);

 

 

GlobalFree(hDib

);

 

 

return true

;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值