VC++中图像处理类CBitmap的用法
简介
CBitmap是MFC框架下的一个图像处理类,可以方便地进行图像的读取、处理和展示。它封装了基本的位图信息和位图文件的操作方法,可以很好地处理bmp、jpg、png等格式的图像。
CBitmap类的常用方法
1. 构造函数
CBitmap提供了多个构造函数,其中最常用的是默认构造函数CBitmap()和参数为位图资源ID的构造函数CBitmap(UINT nIDResource)。
例如:
CBitmap bmp; // 创建一个空指针
bmp.LoadBitmap(IDB_BITMAP1); // 加载位图资源
2. 位图信息的获取
CBitmap提供了GetBitmap()方法用于获取位图信息。
例如:
BITMAP bmpInfo;
bmp.GetBitmap(&bmpInfo); // 获取位图信息
TRACE("bmp Width:%d, Height:%d", bmpInfo.bmWidth, bmpInfo.bmHeight);
3. 位图文件的加载
CBitmap提供了LoadBitmap()方法用于加载资源中的位图文件,也提供了LoadImage()方法用于加载磁盘上的位图文件。
例如:
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1); // 加载位图资源
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, "C:\\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
bmp.Attach(hBmp); // 将位图文件附加到CBitmap对象
4. 位图的绘制
CBitmap提供了很多不同类型的Draw()方法用于在设备环境中绘制位图。
例如:
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1); // 加载位图资源
CDC *pDC = GetDC();
CDC dcMem;
dcMem.CreateCompatibleDC(pDC); // 创建和当前设备环境兼容的设备环境
dcMem.SelectObject(bmp); // 选择当前的位图
pDC->BitBlt(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, &dcMem, 0, 0, SRCCOPY);
ReleaseDC(pDC);
FreeDC(dcMem);
5. 位图文件的保存
CBitmap提供了SaveImage()方法用于将位图文件保存到磁盘上。
例如:
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1); // 加载位图资源
BITMAP bmpInfo;
bmp.GetBitmap(&bmpInfo); // 获取位图信息
CImage image;
image.Attach(bmp);
image.Save(_T("C:\\test.jpg"), Gdiplus::ImageFormatJPEG);
示例一:将位图文件转换成灰度图像
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1); // 加载位图资源
BITMAP bmpInfo;
bmp.GetBitmap(&bmpInfo); // 获取位图信息
int nWidth = bmpInfo.bmWidth;
int nHeight = bmpInfo.bmHeight;
CImage image;
image.Create(nWidth, nHeight, 8, 0); // 创建一张8位深度的位图
CDC dc;
dc.CreateCompatibleDC(NULL);
dc.SelectObject(image);
dc.BitBlt(0, 0, nWidth, nHeight, &dc, 0, 0, SRCCOPY); // 原图赋值到新位图中
for (int i = 0; i < nWidth; i++)
{
for (int j = 0; j < nHeight; j++)
{
COLORREF color = dc.GetPixel(i, j);
BYTE red = GetRValue(color);
BYTE green = GetGValue(color);
BYTE blue = GetBValue(color);
BYTE gray = static_cast<BYTE>((red + green + blue) / 3.0);
dc.SetPixel(i, j, RGB(gray, gray, gray));
}
}
image.Save(_T("C:\\test_gray.bmp"), Gdiplus::ImageFormatBMP);
示例二:叠加一个png图像到jpg图像上
CImage image;
image.Load(_T("C:\\test.jpg")); // 加载jpg图像
CImage image2;
image2.Load(_T("C:\\test.png")); // 加载png图像
CDC dc;
dc.CreateCompatibleDC(NULL);
dc.SelectObject(image);
CDC dc2;
dc2.CreateCompatibleDC(NULL);
dc2.SelectObject(image2);
BITMAP bmpInfo;
image.GetBitmap(&bmpInfo);
BITMAPINFO bmp;
ZeroMemory(&bmp, sizeof(BITMAPINFO));
bmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmp.bmiHeader.biWidth = bmpInfo.bmWidth;
bmp.bmiHeader.biHeight = bmpInfo.bmHeight;
bmp.bmiHeader.biPlanes = 1;
bmp.bmiHeader.biBitCount = 24;
bmp.bmiHeader.biCompression = BI_RGB;
BYTE *pSrcData = NULL;
image2.GetBitmapBits(bmpInfo.bmWidthBytes * bmpInfo.bmHeight, pSrcData);
BYTE *pDestData = NULL;
image.GetBitmapBits(bmpInfo.bmWidthBytes * bmpInfo.bmHeight, pDestData);
for (int i = 0; i < bmpInfo.bmWidth; i++)
{
for (int j = 0; j < bmpInfo.bmHeight; j++)
{
BYTE R, G, B;
R = pDestData[(j * bmpInfo.bmWidth + i) * 3 + 2];
G = pDestData[(j * bmpInfo.bmWidth + i) * 3 + 1];
B = pDestData[(j * bmpInfo.bmWidth + i) * 3];
BYTE alpha = pSrcData[(j * bmpInfo.bmWidth + i) * 4 + 3];
BYTE R2, G2, B2;
R2 = pSrcData[(j * bmpInfo.bmWidth + i) * 4 + 2];
G2 = pSrcData[(j * bmpInfo.bmWidth + i) * 4 + 1];
B2 = pSrcData[(j * bmpInfo.bmWidth + i) * 4];
pDestData[(j * bmpInfo.bmWidth + i) * 3 + 2] = static_cast<BYTE>((R * (255 - alpha) + R2 * alpha) / 255.f);
pDestData[(j * bmpInfo.bmWidth + i) * 3 + 1] = static_cast<BYTE>((G * (255 - alpha) + G2 * alpha) / 255.f);
pDestData[(j * bmpInfo.bmWidth + i) * 3] = static_cast<BYTE>((B * (255 - alpha) + B2 * alpha) / 255.f);
}
}
image.Save(_T("C:\\test_result.jpg"), Gdiplus::ImageFormatJPEG);
结语
本文简单介绍了CBitmap类的一些常用方法,并且给出了两个简单的示例,希望读者可以在实际应用中更好地掌握CBitmap类的用法。当然,本文仅仅提供了一些简单的例子,实际的图像处理过程可能更加复杂,需要考虑到文件格式、速度等一系列因素,需要读者自行进一步学习去研究。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:VC++中图像处理类CBitmap的用法 - Python技术站