如何把屏幕DC所画的内容写入文件(BMP)
问题点数:40、回复次数:4Top
1 楼masterz(www.fruitfruit.com)回复于 2002-01-06 21:41:06 得分 0
http://www.csdn.net/expert/Topic/451/451543.shtm
http://www.csdn.net/expert/Topic/426/426088.shtmTop
2 楼HowUCan(提前考虑风险,否则总是救火)回复于 2002-01-06 21:44:37 得分 10
//函数功能:将一幅位图转换为24位DIB保存到文件中
//参数:hBmp: 要保存位图的句柄
// hdc: 设备相关位图的DC 此dc中selectobject选择 hBmp
// file: 文件指针
void mySaveBmp(HBITMAP hBmp, HDC hdc, CFile* file)
{
if(!hBmp) return;
if(!hdc) return;
//转换成DIB
BITMAP bmp;
if(!GetObject(hBmp, sizeof(BITMAP), &bmp)) return;
BITMAPINFOHEADER BmpInfoHeader;
BYTE * pBits;
BmpInfoHeader.biSize = sizeof (BITMAPINFOHEADER) ;
BmpInfoHeader.biWidth = bmp.bmWidth ;
BmpInfoHeader.biHeight = bmp.bmHeight ;
BmpInfoHeader.biPlanes = 1 ;
BmpInfoHeader.biBitCount = 24 ;
BmpInfoHeader.biCompression = BI_RGB ;
BmpInfoHeader.biSizeImage = 0 ;
BmpInfoHeader.biXPelsPerMeter = 0 ;
BmpInfoHeader.biYPelsPerMeter = 0 ;
BmpInfoHeader.biClrUsed = 0 ;
BmpInfoHeader.biClrImportant = 0 ;
HBITMAP hDIBmp = CreateDIBSection (NULL, (BITMAPINFO *) &BmpInfoHeader, 0, (void**)&pBits, NULL, 0) ;
//GetDIBits的第一个参数一定不能是NULL,否则全黑
int nResult = GetDIBits(hdc, hBmp, 0, bmp.bmHeight, pBits, (BITMAPINFO *) &BmpInfoHeader, DIB_RGB_COLORS);
//保存DIB
int nPixelSize = 4 * ((bmp.bmWidth * 24 + 31) / 32) * bmp.bmHeight; //象素位的字节数
BITMAPFILEHEADER bmpFileHdr;
bmpFileHdr.bfType = 0x4D42; //BM
bmpFileHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + BmpInfoHeader.biSize;
bmpFileHdr.bfSize = bmpFileHdr.bfOffBits + nPixelSize;
bmpFileHdr.bfReserved1 = 0;
bmpFileHdr.bfReserved2 = 0;
file->Write(&bmpFileHdr, sizeof(BITMAPFILEHEADER));
file->Write(&BmpInfoHeader, BmpInfoHeader.biSize);
file->WriteHuge(pBits, nPixelSize);
//释放资源
DeleteObject(hDIBmp);
}
Top
3 楼JetCodeSun(影刀)回复于 2002-01-06 21:53:41 得分 30
一个例子,网上多的很。
CString dt;
CTime m_CurDT;
m_CurDT=CTime::GetCurrentTime();
dt.Format("%d-%d-%d ",m_CurDT.GetYear(),m_CurDT.GetMonth(),m_CurDT.GetDay());
dt+=m_CurDT.Format("%H时%M分%S秒");
dt+=".bmp";
CString bmpname;
bmpname="c:\\";
bmpname+=dt;
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
int nX, nY, nX2, nY2;
// 位图宽度和高度
int xScrn, yScrn;
// 屏幕分辨率
HBITMAP hBitmap, hOldBitmap;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
// 获得全屏坐标
nX = 0;
nY = 0;
nX2 = xScrn;
nY2 = yScrn;
// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap(hScrDC, nX2, nY2);
// 把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nX2, nY2, hScrDC, nX, nY, SRCCOPY);
//得到屏幕位图的句柄
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
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;
else
wBitCount = iBits;
//计算调色板大小
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,(BITMAPINFO*)lpbi,DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}
//创建位图文件
fh = CreateFile(bmpname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
// 设置位图文件头
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);
Top
4 楼Kendiv(自由蚂蚁 with SP4)回复于 2002-01-06 22:18:48 得分 0
upupupTop




