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);
    }



  • 相关阅读:
    题解:luoguP1861 星之器
    题解:LOJ540游戏
    Yii框架常见问题
    常用ubuntu命令
    Python中的映射数据类型 dict
    Python中的编码问题:ASCII码 Unicoden编码 UTF8编码
    Python中的列表、元组的增、删、改、查
    Python 数据类型之 集合 set
    Python中常见的字符串的操作方法:
    Python程序的控制结构用多分支结构处理身体指标BMI问题
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/6725975.html
Copyright © 2011-2022 走看看