zoukankan      html  css  js  c++  java
  • [ATL/WTL]_[中级]_[保存CBitmap到文件-保存屏幕内容到文件]


    场景:

    1. 在做图片处理时,比方放大后或加特效后须要保存CBitmap(HBITMAP)到文件.

    2.截取屏幕内容到文件时.

    3.不须要增加第3方库时.


    说明: 这段代码部分来自网上。第一次学atl/wtl。gdi不是非常熟悉。以后转换为wtl版本号吧。

    当然wtl项目直接用也没问题. 如今想想wxWidgets的wxImage类对这类操作方便多了。仅仅须要调用一个SaveFile方法。


    保存HBITMAP到文件:

    static bool SaveBitmapToFile(CBitmap& bitmap, LPWSTR lpFileName)
    {            
    	HBITMAP hBitmap;	// 为刚才的屏幕位图句柄
    	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;
    	
    	//计算位图文件每一个像素所占字节数  
    	hBitmap = bitmap;  
    	hDC = CreateDC(L"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 if (iBits <= 32)
    		wBitCount = 32;
    	
    	//计算调色板大小  
    	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;	
    }  

    保存屏幕到文件:

    static void SaveScreenToFile(LPCTSTR szFileName)
    {
    	HDC hScrDC = ::GetDC(NULL);
    	HDC hMemDC = NULL;
    
    	BYTE *lpBitmapBits = NULL; 
    
    	int nWidth = GetSystemMetrics(SM_CXSCREEN);
    	int nHeight = GetSystemMetrics(SM_CYSCREEN); 
    
    	hMemDC = ::CreateCompatibleDC(hScrDC); 
    
    	BITMAPINFO bi; 
    	ZeroMemory(&bi, sizeof(BITMAPINFO));
    	bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    	bi.bmiHeader.biWidth = nWidth;
    	bi.bmiHeader.biHeight = nHeight;
    	bi.bmiHeader.biPlanes = 1;
    	bi.bmiHeader.biBitCount = 24;
    
    	HBITMAP bitmap = ::CreateDIBSection(hMemDC, &bi, DIB_RGB_COLORS, (LPVOID*)&lpBitmapBits, NULL, 0);
    	HGDIOBJ oldbmp = ::SelectObject(hMemDC, bitmap); 
    
    	::BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, 0, 0, SRCCOPY);
    
    	BITMAPFILEHEADER bh;
    	ZeroMemory(&bh, sizeof(BITMAPFILEHEADER));
    	bh.bfType = 0x4d42; //bitmap 
    	bh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    	bh.bfSize = bh.bfOffBits + ((nWidth*nHeight)*3);
    
    	FILE* file = _wfopen(szFileName,L"wb");
    	if(file)
    	{ 
    		fwrite(&bh,1,sizeof(BITMAPFILEHEADER),file);
    		fwrite(&(bi.bmiHeader),1,sizeof(BITMAPINFOHEADER),file);
    		fwrite(lpBitmapBits,1,3 * nWidth * nHeight,file);
    		fclose(file);
    	}
    
    	::SelectObject(hMemDC, oldbmp);
    	::DeleteObject(bitmap);
    	::DeleteObject(hMemDC);
    	::ReleaseDC(NULL, hScrDC);
    }



  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 数的统计
    Java实现 蓝桥杯VIP 算法训练 和为T
    Java实现 蓝桥杯VIP 算法训练 友好数
    Java实现 蓝桥杯VIP 算法训练 连续正整数的和
    Java实现 蓝桥杯VIP 算法训练 寂寞的数
    Java实现 蓝桥杯VIP 算法训练 学做菜
    Java实现 蓝桥杯VIP 算法训练 暗恋
    Java实现 蓝桥杯VIP 算法训练 暗恋
    测试鼠标是否在窗口内,以及测试鼠标是否在窗口停留
    RichEdit 各个版本介绍
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/6725975.html
Copyright © 2011-2022 走看看