c++将剪贴板内容保存为bmp图

C++读取word数据,word在剪贴板中的数据类型是HENHMETAFILE。

1.读取剪贴板数据转存emf文件
void CTestClipBoardDlg::SaveAsEMF(CString csEMFname)
{
	if(!OpenClipboard())
	{
		return;
	}

	for(int i=1; i<16; i++)
	{
		UINT   nRet1 = EnumClipboardFormats(i); 
		CString str;
		str.Format("%d\n",i);
		if(nRet1)
			TRACE("[ok]"+str);
		else
			TRACE("[error]"+str);
	}

	DWORD   dwError;
	UINT nRet = EnumClipboardFormats(CF_ENHMETAFILE);

	if(nRet) 
	{ 
		BOOL   ba=::IsClipboardFormatAvailable(CF_ENHMETAFILE);   
		HANDLE   hClip=::GetClipboardData(CF_ENHMETAFILE);
		HENHMETAFILE hEnhMetaFile;
		hEnhMetaFile=(HENHMETAFILE)hClip; 		 
		dwError=GetLastError();   //dwError=6,无效的句柄。   

//		CString str = "d:\\aaa.emf";
		HENHMETAFILE   hMetaFile=CopyEnhMetaFile(hEnhMetaFile, csEMFname);//保存到文件

		//关闭CMetafileDC并获得它的句柄
		DeleteEnhMetaFile(hMetaFile);
		dwError=GetLastError();   //dwError=6,无效的句柄。 

		CClientDC dc(this);
		CRect client(0,0,600,400);
		dc.PlayMetaFile(hEnhMetaFile,client);
	} 
	::CloseClipboard();
}



2.emf文件转存bmp
bool CTestClipBoardDlg::ConvertEMFToBMP(const char * pszEMFFile,const char* pszBMPFile,BOOL bScaleImage/*=false*/)
{ 
	char szBMPFile[255] = "";   
	strcpy(szBMPFile,pszBMPFile);//bmp文件名   

	//将EMF文件转换为bmp文件  
	BOOL bRet = ConvertToBMP(pszEMFFile,(const char*)szBMPFile,bScaleImage);   

	//如果转换失败返回false 
	if(bRet == FALSE)   
	{   
		return FALSE;   
	}
	else
	{
// 		CImage m_img;
// 		m_img.Load(_T("d:\\aaa.bmp"));
// 		m_img.Save(_T("d:\\aaa.jpg"));
	}
 
	return bRet ? TRUE:FALSE;   
}


HANDLE CTestClipBoardDlg::DDBToDIB(HBITMAP bitmap, DWORD dwCompression, HPALETTE pPal)
{
	BITMAP          bm;   
	BITMAPINFOHEADER    bi;   
	LPBITMAPINFOHEADER  lpbi;   
	DWORD           dwLen;   
	HANDLE          hDIB;   
	HANDLE          handle;   
	HDC             hDC;   
	HPALETTE        hPal;   
 
	if( dwCompression == BI_BITFIELDS )   
		return NULL;   

	//如果没有指定调色板,采用默认的 
	hPal = (HPALETTE) pPal;   
	if (hPal==NULL)   
		hPal = (HPALETTE) ::GetStockObject(DEFAULT_PALETTE);   

	// 获取bitmap信息 
	::GetObject(bitmap,sizeof(bm),(LPSTR)&bm);   

	//初始化bitmap信息头  
	bi.biSize       = sizeof(BITMAPINFOHEADER);   
	bi.biWidth      = bm.bmWidth;   
	bi.biHeight         = bm.bmHeight;   
	bi.biPlanes         = 1;   
	bi.biBitCount       = bm.bmPlanes * bm.bmBitsPixel;   
	bi.biCompression    = dwCompression;   
	bi.biSizeImage      = 0;   
	bi.biXPelsPerMeter  = 0;   
	bi.biYPelsPerMeter  = 0;   
	bi.biClrUsed        = 0;   
	bi.biClrImportant   = 0;   

	// 计算信息头和调色板大小  
	int nColors = (1 << bi.biBitCount);   
	if( nColors > 256 )    
		nColors = 0;   
	dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);   

	// We need a device context to get the DIB from   
	hDC = ::GetDC(NULL);   
	hPal = SelectPalette(hDC,hPal,FALSE);   
	RealizePalette(hDC);   

	// 申请内存 
	hDIB = GlobalAlloc(GMEM_FIXED,dwLen);   
	if (!hDIB)   
	{   
		SelectPalette(hDC,hPal,FALSE);   
		::ReleaseDC(NULL,hDC);   
		return NULL;   
	}   

	lpbi = (LPBITMAPINFOHEADER)hDIB;   
	*lpbi = bi;   

	// Call GetDIBits with a NULL lpBits param, so the device driver    
	// will calculate the biSizeImage field    
	GetDIBits(hDC, (HBITMAP)bitmap, 0L, (DWORD)bi.biHeight,   
		(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);   


	bi = *lpbi;   
	// If the driver did not fill in the biSizeImage field, then compute it   
	// Each scan line of the image is aligned on a DWORD (32bit) boundary   
	if (bi.biSizeImage == 0)   
	{   
		bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)* bi.biHeight;   

		// If a compression scheme is used the result may infact be larger   
		// Increase the size to account for this.   
		if (dwCompression != BI_RGB)   
			bi.biSizeImage = (bi.biSizeImage * 3) / 2;   
	}   


	// Realloc the buffer so that it can hold all the bits   
	dwLen += bi.biSizeImage;   
	if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))   
	{   
		hDIB = handle;   
	}   
	else   
	{   
		GlobalFree(hDIB);   

		// Reselect the original palette   
		SelectPalette(hDC,hPal,FALSE);   
		::ReleaseDC(NULL,hDC);   
		return NULL;   
	}   

	// Get the bitmap bits   
	lpbi = (LPBITMAPINFOHEADER)hDIB;   

	// FINALLY get the DIB   
	BOOL bGotBits = GetDIBits( hDC, bitmap,   
		0L,             // Start scan line   
		(DWORD)bi.biHeight,     // # of scan lines   
		(LPBYTE)lpbi            // address for bitmap bits  
		+ (bi.biSize + nColors * sizeof(RGBQUAD)),   
		(LPBITMAPINFO)lpbi,     // address of bitmapinfo   
		(DWORD)DIB_RGB_COLORS);     // Use RGB for color table   

	if( !bGotBits )
	{   
		GlobalFree(hDIB);   
		SelectPalette(hDC,hPal,FALSE);   
		::ReleaseDC(NULL,hDC);   
		return NULL;   
	}   
	SelectPalette(hDC,hPal,FALSE);   
	::ReleaseDC(NULL,hDC);   

	return hDIB;   
}


bool CTestClipBoardDlg::WriteDIB(char * szFile, HANDLE hDIB)
{
	BITMAPFILEHEADER    hdr;   
	LPBITMAPINFOHEADER  lpbi;   

	if (!hDIB)   
		return FALSE;   

	FILE* file;   
	file = fopen(szFile,"wb");   

	if(file == NULL)   
		return FALSE;   

	lpbi = (LPBITMAPINFOHEADER)hDIB;    
	int nColors = 0;    
	if(lpbi->biBitCount <= 8)    
	{    
		nColors = (1 << lpbi->biBitCount);    
	}    

	// Fill in the fields of the file header    
	hdr.bfType = ((WORD) ('M' << 8) | 'B');  // is always "BM"   
	hdr.bfSize = GlobalSize(hDIB) + sizeof( hdr );   
	hdr.bfReserved1 = 0;   
	hdr.bfReserved2 = 0;   
	hdr.bfOffBits = (DWORD) (sizeof( hdr ) + lpbi->biSize + nColors * sizeof(RGBQUAD));   

	// Write the file header    
	fwrite(&hdr, sizeof(hdr),1,file);   


	// Write the DIB header and the bits    
	fwrite(lpbi, GlobalSize(hDIB),1,file);   


	//Close the file and return   
	fclose(file);   

	return TRUE;   
}


bool CTestClipBoardDlg::SetBackColorToWhite(HDC pDC)
{
	// Set brush to desired background color     
	HBRUSH backBrush= (HBRUSH)::GetStockObject(WHITE_BRUSH);
	// Save old brush   
	HBRUSH pOldBrush = (HBRUSH)::SelectObject(pDC,backBrush);   
	RECT rect ;   
	::GetClipBox(pDC,&rect); // Erase the area needed   

	//paint the given rectangle using the brush that is currently selected    
	//into the specified device context   
	::PatBlt(pDC,rect.left, rect.top, abs(rect.left - rect.right),abs(rect.top-rect.bottom ),PATCOPY);   


	//Select back the old brush   
	::SelectObject(pDC,pOldBrush);   

	return TRUE;       
}

bool CTestClipBoardDlg::ConvertToBMP(const char * strFileName,const char* strBMPFile,BOOL bScaleImage)
{
	//Declartions   
	HENHMETAFILE hemf;   
	HBITMAP     bitmap;   
	HDC         memDC;   
	ENHMETAHEADER   emh;   

	//Get the DC of the Window   
	HDC dc = ::GetDC(NULL);   

	//Get the Handle from the enhanced metafile   
	hemf = GetEnhMetaFile(strFileName);

	// Get the header from the enhanced metafile.   
	ZeroMemory( &emh, sizeof(ENHMETAHEADER) );   
	emh.nSize = sizeof(ENHMETAHEADER);   

	if( GetEnhMetaFileHeader( hemf, sizeof( ENHMETAHEADER ), &emh ) == 0 )   
	{   
		DeleteEnhMetaFile( hemf );   
		return FALSE;   
	}   

	//Declare variables for calculation of metafile rect   
	RECT    rect;   
	float   PixelsX, PixelsY, MMX, MMY;   
	float fAspectRatio;   
	long lWidth,lHeight;   

	// Get the characteristics of the output device.   
	PixelsX = (float)GetDeviceCaps( dc, HORZRES );   
	PixelsY = (float)GetDeviceCaps( dc, VERTRES );   
	MMX = (float)GetDeviceCaps( dc, HORZSIZE );   
	MMY = (float)GetDeviceCaps( dc, VERTSIZE );   


	// Calculate the rect in which to draw the metafile based on the   
	// intended size and the current output device resolution.   
	// Remember that the intended size is given in 0.01 mm units, so   
	// convert those to device units on the target device.   
	rect.top = (int)((float)(emh.rclFrame.top) * PixelsY / (MMY*100.0f));   
	rect.left = (int)((float)(emh.rclFrame.left) * PixelsX / (MMX*100.0f));   
	rect.right = (int)((float)(emh.rclFrame.right) * PixelsX / (MMX*100.0f));   
	rect.bottom = (int)((float)(emh.rclFrame.bottom) * PixelsY / (MMY*100.0f));   


	//Calculate the Width and Height of the metafile   
	lWidth = (long)((float)(abs(rect.left - rect.right)));   
	lHeight =(long)((float)(abs(rect.top-rect.bottom )));   

	fAspectRatio = (float)lWidth/(float)lHeight;   


	if(bScaleImage) //If miniature option is ON, change the width and height accordingly   
	{   
		if(fAspectRatio > 1 ) //width is more than height    
		{   
			//Make width as constant and calculate Height   
// 			lWidth = X_MINIATUREFRAME;   
// 			lHeight = (long)((float)Y_MINIATUREFRAME / fAspectRatio);   
		}   
		else //width is less than height(or equal to height)   
		{   
			//Make Height as constant and calculate Width   
// 			lHeight = Y_MINIATUREFRAME;   
// 			lWidth = (long)((float)X_MINIATUREFRAME * fAspectRatio);   
		}   

	}   

	//Populate the rect structure   
	rect.left = 0;   
	rect.top = 0;   
	rect.right = lWidth;   
	rect.bottom = lHeight;   

	//Create a Memory DC compatible to WindowDC   
	memDC=::CreateCompatibleDC(dc);    


	//Create a bitmap compatible to Window DC   
	bitmap = ::CreateCompatibleBitmap(dc,lWidth,lHeight);   

	DWORD dwRetError = GetLastError();   


	//Select the bitmap into the Mem DC   
	::SelectObject(memDC,bitmap);   


	//Paint the background of the DC to White   
	SetBackColorToWhite(memDC);   


	//Now play the enhanced metafile into the memory DC; ignore its return value   
	//it may be false even if successful   
	PlayEnhMetaFile(memDC,hemf,&rect);     
	DWORD dwRet = GetLastError();   


	// Create logical palette if device support a palette   
	HPALETTE pal;   
	if( GetDeviceCaps(dc,RASTERCAPS) & RC_PALETTE )   
	{   
		UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);   
		LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];   
		pLP->palVersion = 0x300;   
		pLP->palNumEntries = GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );   

		// Create the palette   
		pal = ::CreatePalette(pLP );   
		delete[] pLP;   

	}   

	// Convert the bitmap to a DIB   
	HANDLE hDIB = DDBToDIB(bitmap, BI_RGB, NULL );   
	if( hDIB == NULL )   
	{   
		DeleteEnhMetaFile( hemf );   
		return FALSE;   
	}   

	// Write it to file   
	WriteDIB((char*)strBMPFile, hDIB );   

	// Free the memory allocated by DDBToDIB for the DIB   
	::GlobalFree( hDIB );   
	::DeleteEnhMetaFile( hemf );   
	::ReleaseDC(NULL,dc);   

	return TRUE;   
}


3.使用
SaveAsEMF("d:\\aaa.emf");//把剪贴板内容存为EMF文件
ConvertEMFToBMP("d:\\aaa.emf","d:\\aaa.bmp",false);//将EMF文件存为BMP文件




  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要将缓存区数据保存BMP 片,可以先将数据复制到一个 std::vector<uint8_t> 中,然后使用上面提到的 SaveBMP 函数将数据保存BMP 文件。以下是一个简单的 C++ 代码示例: ```c++ #include <fstream> #include <iostream> #include <vector> struct BMPHeader { // BMP 文件头 uint16_t bfType; // 文件类型,必须为 "BM" uint32_t bfSize; // 文件大小 uint16_t bfReserved1; // 保留字段 uint16_t bfReserved2; // 保留字段 uint32_t bfOffBits; // 数据偏移量 // BMP 信息头 uint32_t biSize; // 信息头大小 int32_t biWidth; // 像宽度 int32_t biHeight; // 像高度 uint16_t biPlanes; // 颜色平面数(必须为1) uint16_t biBitCount; // 每个像素的位数 uint32_t biCompression; // 压缩类型(0=不压缩) uint32_t biSizeImage; // 像数据大小 int32_t biXPelsPerMeter; // 水平分辨率 int32_t biYPelsPerMeter; // 垂直分辨率 uint32_t biClrUsed; // 颜色表中的颜色数 uint32_t biClrImportant; // 重要颜色数 }; void SaveBMP(const char* filename, const std::vector<uint8_t>& data, int width, int height, int bitsPerPixel) { BMPHeader header = {}; // 设置文件头 header.bfType = 0x4D42; // "BM" header.bfOffBits = sizeof(BMPHeader); // 数据偏移量 header.biSize = 40; // 信息头大小 header.biWidth = width; header.biHeight = height; header.biPlanes = 1; header.biBitCount = bitsPerPixel; header.biSizeImage = data.size(); // 打开文件 std::ofstream file(filename, std::ios::binary); if (!file.is_open()) { std::cerr << "Failed to open file " << filename << " for writing.\n"; return; } // 写入文件头 file.write(reinterpret_cast<char*>(&header), sizeof(BMPHeader)); // 写入像数据 file.write(reinterpret_cast<const char*>(data.data()), data.size()); // 关闭文件 file.close(); std::cout << "Saved BMP file " << filename << ".\n"; } int main() { // 假设我们有一个缓存区 buffer,存储了一个 640x480 的灰度像 int width = 640; int height = 480; int bitsPerPixel = 8; // 灰度像,每个像素占 8 位 std::vector<uint8_t> imageData(width * height); // 存储像数据 // 将缓存区数据复制到 imageData 中 // ... SaveBMP("image.bmp", imageData, width, height, bitsPerPixel); return 0; } ``` 在上面的代码中,我们假设有一个缓存区 buffer,存储了一个 640x480 的灰度像。我们首先定义了像的宽度、高度和每个像素的位数,并创建了一个 std::vector<uint8_t> imageData 来存储像数据。接下来,我们将缓存区数据复制到 imageData 中。最后,我们调用 SaveBMP 函数将 imageData 中的数据保存BMP 文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值