把位图保存为文件源代码

最近想写一个截图工具,就研究了一下位图的结构。下面代码是把位图以BMP文件的结构写入文件中的
#include <Windows.h>

BOOL SaveBitmapToFile(LPCTSTR lpszFilePath, HBITMAP hBm)
{
	//  定义位图文件表头
	BITMAPFILEHEADER bmfh;
	//  定义位图信息表头
	BITMAPINFOHEADER bmih;

	//  调色板长度
	int nColorLen = 0;
	//  调色表大小
	DWORD dwRgbQuadSize = 0;
	//  位图大小
	DWORD dwBmSize = 0;
	//  分配内存的指针
	HGLOBAL	hMem = NULL;

	LPBITMAPINFOHEADER 	lpbi;

	BITMAP bm;
	
	HDC hDC;

	HANDLE hFile = NULL;

	DWORD dwWritten;

	GetObject(hBm, sizeof(BITMAP), &bm);

	bmih.biSize	= sizeof(BITMAPINFOHEADER);	// 本结构所占的字节
	bmih.biWidth	= bm.bmWidth;			// 位图宽
	bmih.biHeight	= bm.bmHeight;			// 位图高
	bmih.biPlanes	= 1;
	bmih.biBitCount		= bm.bmBitsPixel;	// 每一图素的位数
	bmih.biCompression	= BI_RGB;			// 不压缩
	bmih.biSizeImage		= 0;  //  位图大小
	bmih.biXPelsPerMeter	= 0;
	bmih.biYPelsPerMeter	= 0;
	bmih.biClrUsed		= 0;
	bmih.biClrImportant	= 0;

	//  计算位图图素数据区大小 
	dwBmSize = 4 * ((bm.bmWidth * bmih.biBitCount + 31) / 32) * bm.bmHeight;

	//  如果图素位 <= 8bit,则有调色板
	if (bmih.biBitCount <= 8)
	{
		nColorLen = (1 << bm.bmBitsPixel);
	}

	//  计算调色板大小
	dwRgbQuadSize = nColorLen * sizeof(RGBQUAD);

	//  分配内存
	hMem = GlobalAlloc(GHND, dwBmSize + dwRgbQuadSize + sizeof(BITMAPINFOHEADER));

	if (NULL == hMem)
	{
		return FALSE;
	}

	//  锁定内存
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hMem);

	//  将bmih中的内容写入分配的内存中
	*lpbi = bmih;

	hDC = GetDC(NULL);

	//  将位图中的数据以bits的形式放入lpData中。
	GetDIBits(hDC, hBm, 0, (DWORD)bmih.biHeight, (LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwRgbQuadSize, (BITMAPINFO *)lpbi, (DWORD)DIB_RGB_COLORS);
	
	bmfh.bfType = 0x4D42;  // 位图文件类型:BM
	bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwRgbQuadSize + dwBmSize;  // 位图大小
	bmfh.bfReserved1 = 0;
	bmfh.bfReserved2 = 0;
	bmfh.bfOffBits	= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwRgbQuadSize;  // 位图数据与文件头部的偏移量

	//  把上面的数据写入文件中

	hFile = CreateFile(lpszFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL);
	
	if (INVALID_HANDLE_VALUE == hFile)
	{
		return FALSE;
	}

	//  写入位图文件头
	WriteFile(hFile, (LPSTR)&bmfh, sizeof(BITMAPFILEHEADER), (DWORD *)&dwWritten, NULL);
	//  写入位图数据
	WriteFile(hFile, (LPBITMAPINFOHEADER)lpbi, bmfh.bfSize - sizeof(BITMAPFILEHEADER), (DWORD *)&dwWritten, NULL);

	GlobalFree(hMem);
	CloseHandle(hFile);

	return TRUE;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是使用 MFC 将 jpg 图像转换为单色位图保存为图像的示例代码: ```cpp // CMyDlg.cpp 文件的代码 // 定义图像处理函数 BOOL CMyDlg::ConvertToMonoChrome(CString strInputFile, CString strOutputFile) { // 加载图像 CImage image; HRESULT hResult = image.Load(strInputFile); if (FAILED(hResult)) { // 加载图像失败 return FALSE; } // 创建目标位图 CBitmap bitmap; hResult = bitmap.CreateBitmap(image.GetWidth(), image.GetHeight(), 1, 1, NULL); if (FAILED(hResult)) { // 创建位图失败 return FALSE; } // 获取目标位图的 DC CDC* pDC = CDC::FromHandle(::GetDC(NULL)); CDC memDC; memDC.CreateCompatibleDC(pDC); CBitmap* pOldBitmap = memDC.SelectObject(&bitmap); // 绘制目标位图 memDC.SetBkColor(RGB(255, 255, 255)); memDC.SetTextColor(RGB(0, 0, 0)); memDC.BitBlt(0, 0, image.GetWidth(), image.GetHeight(), pDC, 0, 0, SRCCOPY); // 保存目标位图为图像文件 hResult = bitmap.Save(strOutputFile, Gdiplus::ImageFormatBMP); if (FAILED(hResult)) { // 保存图像失败 return FALSE; } // 清理资源 memDC.SelectObject(pOldBitmap); return TRUE; } // 调用图像处理函数 void CMyDlg::OnConvertImage() { CString strInputFile = _T("input.jpg"); CString strOutputFile = _T("output.bmp"); if (ConvertToMonoChrome(strInputFile, strOutputFile)) { MessageBox(_T("转换成功!")); } else { MessageBox(_T("转换失败!")); } } ``` 上述代码,`ConvertToMonoChrome` 函数将首先加载 jpg 图像,然后创建一个单色位图,并绘制 jpg 图像的副本,使用黑色和白色的颜色,以便将其转换为单色位图。 然后,函数将保存单色位图为 BMP 图像文件。 在 `OnConvertImage` 函数,我们可以指定输入和输出文件名,并调用 `ConvertToMonoChrome` 函数,将 jpg 图像转换为单色位图保存为 BMP 图像文件。 请注意,此示例代码使用了 GDI+ 库,因此需要添加 `#include <gdiplus.h>` 头文件,并在链接时添加 `gdiplus.lib` 库文件。 ### 回答2: MFC是一种用于开发Windows平台应用程序的框架,可以用于图像处理和图形显示等功能。要将JPG图像转换为单色位图保存为图片,可以使用MFC提供的图像处理函数和图形库来完成。 下面是一个示例代码实现的步骤: 1. 使用CImage类加载JPG图像文件,可以使用Load()函数实现,确保已包含头文件"atlimage.h"。 2. 将图像转换为灰度图像,使用灰度算法可以将彩色图像转换为单色灰度图像。使用函数ConvertToGrayscale()实现。 可以使用GetPixel()和SetPixel()函数遍历每个像素点进行转换。 3. 创建一个新的单色位图对象,可以使用CBitmap类来创建,确保已包含头文件"afxwin.h"。 4. 使用CreateBitmap()函数创建一个与转换后的图像大小相同的单色位图。 5. 将转换后的图像数据复制到新的单色位图,使用SetBitmapBits()函数实现。 6. 使用CImage类保存新的单色位图为图片文件,使用Save()函数实现。 以下是示例代码的实现: ```cpp #include <atlimage.h> #include <afxwin.h> void ConvertImageToSingleColorBitmap(const CString& imagePath, const CString& savePath) { // 加载图像 CImage image; image.Load(imagePath); // 转换为灰度 CImage grayImage; grayImage.Create(image.GetWidth(), image.GetHeight(), 8 * image.GetBPP()); for (int y = 0; y < image.GetHeight(); y++) { for (int x = 0; x < image.GetWidth(); x++) { COLORREF color = image.GetPixel(x, y); int grayValue = GetRValue(color) * 0.3 + GetGValue(color) * 0.59 + GetBValue(color) * 0.11; grayImage.SetPixel(x, y, RGB(grayValue, grayValue, grayValue)); } } // 创建单色位图对象 CBitmap bitmap; bitmap.CreateBitmap(grayImage.GetWidth(), grayImage.GetHeight(), 1, 1, nullptr); // 复制图像数据到单色位图 bitmap.SetBitmapBits(sizeof(BYTE) * grayImage.GetWidth() * grayImage.GetHeight(), grayImage.GetBits()); // 保存为图片文件 CImage bitmapImage; bitmapImage.Attach(bitmap); bitmapImage.Save(savePath); } ``` 使用上述函数,可以将给定的JPG图像转换为单色位图,并保存为图片文件。调用`ConvertImageToSingleColorBitmap("source.jpg", "output.bmp")`来实现转换和保存操作,其`source.jpg`是源JPG图像文件路径,而`output.bmp`是保存的目标单色位图文件路径。 ### 回答3: 在MFC,可以通过以下步骤将jpg图转换成单色位图保存成图片。 1. 导入所需的头文件: ```cpp #include <afxwin.h> #include <afxdialogex.h> #include <atlimage.h> ``` 2. 创建一个MFC应用程序或对现有应用程序进行修改,在Dialog类的成员函数添加以下代码: ```cpp void CMyDialog::ConvertJpgToMonoBitmap(const CString& jpgFilePath, const CString& monoBitmapFilePath) { // 加载jpg图像 CImage img; HRESULT hr = img.Load(jpgFilePath); if (FAILED(hr)) { AfxMessageBox(_T("无法加载jpg图像")); return; } // 创建与原图尺寸相同的单色位图 CBitmap monoBitmap; monoBitmap.CreateBitmap(img.GetWidth(), img.GetHeight(), 1, 1, nullptr); // 创建DC和位图对象 CDC* dc = GetDC(); CDC memDC; memDC.CreateCompatibleDC(dc); CBitmap* pOldBitmap = memDC.SelectObject(&monoBitmap); // 将彩色图像复制到单色位图 memDC.BitBlt(0, 0, img.GetWidth(), img.GetHeight(), dc, 0, 0, SRCCOPY); // 保存单色位图为图片文件 monoBitmap.Save(monoBitmapFilePath, Gdiplus::ImageFormatBMP); // 清理资源 memDC.SelectObject(pOldBitmap); ReleaseDC(dc); monoBitmap.DeleteObject(); } ``` 3. 在Dialog类的消息映射,添加转换和保存图像的代码: ```cpp BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx) // 其他消息映射 ON_BN_CLICKED(IDC_BUTTON_CONVERT, &CMyDialog::OnBnClickedButtonConvert) END_MESSAGE_MAP() // 点击Button Convert按钮的响应函数 void CMyDialog::OnBnClickedButtonConvert() { CString jpgFilePath = _T("C:\\path\\to\\input.jpg"); CString monoBitmapFilePath = _T("C:\\path\\to\\output.bmp"); ConvertJpgToMonoBitmap(jpgFilePath, monoBitmapFilePath); } ``` 注意:此代码假定已经包含GDI+库和相关MFC头文件,且处理的图像为24位彩色图像。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值