c++将DC保存为BMP图片

最近要做一个截图保存的小模块。其实思路很简单,就是将一直图片的一部分复制到内存DC的Bitmap中,然后将此bitmap保存为BMP图片,具体方法如下:

步骤一:

将要保存DC和区域大小选入到函数:HBITMAP CopyDCToBitmap(HDC hScrDC, LPRECT lpRect)

函数实现:

HBITMAP CopyDCToBitmap(HDC hScrDC, LPRECT lpRect)     
{     
	HDC  hMemDC;                 
	//   屏幕和内存设备描述表     
	HBITMAP hBitmap,hOldBitmap;           
	//   位图句柄     
	int  nX, nY, nX2, nY2;                 
	//   选定区域坐标     
	int  nWidth, nHeight;                 
	//   位图宽度和高度     

	//   确保选定区域不为空矩形     
	if   (IsRectEmpty(lpRect))     
		return   NULL;     

	//   获得选定区域坐标     
	nX   = lpRect->left;     
	nY   = lpRect->top;     
	nX2  = lpRect->right;     
	nY2  = lpRect->bottom;     
	nWidth  = nX2 - nX;     
	nHeight = nY2 - nY;     
	//   为屏幕设备描述表创建兼容的内存设备描述表     
	hMemDC  = CreateCompatibleDC(hScrDC);     
	//   创建一个与屏幕设备描述表兼容的位图,函数需要与CreateCompatibleDC配合使用     
	hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);     
	//   把新位图选到内存设备描述表中     
	hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);     
	//   把屏幕设备描述表拷贝到内存设备描述表中  
	//   StretchBlt函数从源矩形中复制一个位图到目标矩形,必要时按目前目标设备设置的模式进行图像的拉伸或压缩。  
	StretchBlt(hMemDC,0,0,nWidth,nHeight,  hScrDC,nX,nY,nWidth,nHeight,SRCCOPY);  // SRCCOPY  
	//BitBlt(hMemDC,   0,   0,   nWidth,   nHeight,hScrDC,   nX,   nY,   SRCCOPY);     
	//   得到屏幕位图的句柄       

	hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);     
	//   清除       

	//DeleteDC(hScrDC);     
	DeleteDC(hMemDC);     
	DeleteObject(hOldBitmap);     
	//   返回位图句柄     
	return   hBitmap;     
}


步骤二:

将Bitmap保存为文件:调用函数:BOOL SaveBmp(HBITMAP hBitmap, LPCWSTR FileName)  

函数实现:

BOOL SaveBmp(HBITMAP hBitmap, LPCWSTR FileName)     
{     
	HDC   hDC;     
	//当前分辨率下每象素所占字节数     
	int   iBits;     
	//位图中每象素所占字节数     
	WORD  wBitCount;     
	//定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数  
	DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;       
	//位图属性结构       
	BITMAP   Bitmap;         
	//位图文件头结构     
	BITMAPFILEHEADER   bmfHdr;         
	//位图信息头结构       
	BITMAPINFOHEADER   bi;         
	//指向位图信息头结构         
	LPBITMAPINFOHEADER lpbi;         
	//定义文件,分配内存句柄,调色板句柄       
	HANDLE  fh, 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;     
	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);       
		//hDC   =   m_pDc->GetSafeHdc();     
		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);  
	}  

	//   创建位图文件   
	CFile bmpFile;
	bmpFile.Open(FileName,CFile::modeCreate|CFile::modeReadWrite);

	//   设置位图文件头       
	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;  
	//   写入位图文件头  
	bmpFile.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER));
	//   写入位图文件其余内容  
	bmpFile.Write((LPSTR)lpbi,dwDIBSize); 
	//   清除  
	GlobalUnlock(hDib);  
	GlobalFree(hDib);  
	bmpFile.Close();
	return TRUE;  
}  

好了,就这么简单!



  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用GDI将BMP图像发送到打印机打印,您需要执行以下步骤: 1. 打开打印机设备上下文(DC): ``` HDC hdcPrinter = CreateDC("WINSPOOL", printerName, NULL, NULL); ``` 其中,`printerName`是您要打印的打印机的名称。 2. 创建一个内存DC,并将BMP图像绘制到该DC上: ``` HDC hdcMem = CreateCompatibleDC(NULL); HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, bmpFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap); BITMAP bm; GetObject(hBitmap, sizeof(BITMAP), &bm); BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); ``` 其中,`bmpFileName`是BMP图像文件的名称。 3. 获取打印机DC的打印机信息: ``` PRINTER_INFO_2 printerInfo; DWORD dwBytesNeeded; GetPrinter(hdcPrinter, 2, NULL, 0, &dwBytesNeeded); BYTE* pBuffer = new BYTE[dwBytesNeeded]; GetPrinter(hdcPrinter, 2, pBuffer, dwBytesNeeded, &dwBytesNeeded); memcpy(&printerInfo, pBuffer, sizeof(PRINTER_INFO_2)); delete[] pBuffer; ``` 4. 创建一个打印机DC,并将其与打印机连接: ``` HDC hdcPrint = CreateDC(NULL, printerInfo.pPrinterName, NULL, NULL); ``` 5. 设置打印机DC的打印机模式,并将内存DC中的BMP图像打印到打印机DC上: ``` DOCINFO di; ZeroMemory(&di, sizeof(DOCINFO)); di.cbSize = sizeof(DOCINFO); StartDoc(hdcPrint, &di); StartPage(hdcPrint); SetMapMode(hdcPrint, MM_ANISOTROPIC); SetViewportExtEx(hdcPrint, bm.bmWidth, bm.bmHeight, NULL); SetWindowExtEx(hdcPrint, bm.bmWidth, bm.bmHeight, NULL); BitBlt(hdcPrint, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); EndPage(hdcPrint); EndDoc(hdcPrint); ``` 6. 释放所有DC和位图: ``` SelectObject(hdcMem, hOldBitmap); DeleteDC(hdcMem); DeleteDC(hdcPrint); DeleteObject(hBitmap); ``` 完整的代码示例: ``` void PrintBmpOnPrinter(LPCTSTR printerName, LPCTSTR bmpFileName) { HDC hdcPrinter = CreateDC("WINSPOOL", printerName, NULL, NULL); HDC hdcMem = CreateCompatibleDC(NULL); HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, bmpFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap); BITMAP bm; GetObject(hBitmap, sizeof(BITMAP), &bm); BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); PRINTER_INFO_2 printerInfo; DWORD dwBytesNeeded; GetPrinter(hdcPrinter, 2, NULL, 0, &dwBytesNeeded); BYTE* pBuffer = new BYTE[dwBytesNeeded]; GetPrinter(hdcPrinter, 2, pBuffer, dwBytesNeeded, &dwBytesNeeded); memcpy(&printerInfo, pBuffer, sizeof(PRINTER_INFO_2)); delete[] pBuffer; HDC hdcPrint = CreateDC(NULL, printerInfo.pPrinterName, NULL, NULL); DOCINFO di; ZeroMemory(&di, sizeof(DOCINFO)); di.cbSize = sizeof(DOCINFO); StartDoc(hdcPrint, &di); StartPage(hdcPrint); SetMapMode(hdcPrint, MM_ANISOTROPIC); SetViewportExtEx(hdcPrint, bm.bmWidth, bm.bmHeight, NULL); SetWindowExtEx(hdcPrint, bm.bmWidth, bm.bmHeight, NULL); BitBlt(hdcPrint, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); EndPage(hdcPrint); EndDoc(hdcPrint); SelectObject(hdcMem, hOldBitmap); DeleteDC(hdcMem); DeleteDC(hdcPrint); DeleteObject(hBitmap); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值