CBitmap转换成GDI+的Bitmap (Image)

GDI与GDI+  图像对象的转化

  (2011-09-23 09:18:58)
   

   GDI对象与设备描述表(DC)息息相关,设备描述表是Windows使用的一个数据结构,用于存储具体设备能力和与如何在设备上重绘一些项目的有关属性信息。而且视频设备的设备描述表还与特定的窗口有关。首先你必须获得一个设备描述表句柄,然后在图形绘制时,你把这个句柄作为一个参数传递给GDI图形绘制函数。当然你也可以把它传递给获得或设置设备描述表有关属性的函数。

   而GDI+对象,你不必使用句柄或者设备描述表。相反,只是简单地创建一个图形对(Graphics),然后以你熟悉的面向对象的编程方式调用它的方法即可,譬如myGraphicsObject.DrawLine(parameters), Graphics对象是GDI+的核心,正如设备描述表是GDI的核心一样,设备描述表(DC)和图形对象(Graphics)在不同的环境下扮演着同样的角色,发挥着类似的作用,但是两者也存在着这质的不同.前者使用基于句柄的编程方法而后者使用面向对象的编程方法。

   GDI与GDI+作为微软对图像处理先后产生的两种解决方法,其之间的兼容问题经常会出现,并且在不同的情况有各自的好处。因此GDI与GDI+之间的转化尤为让人头疼,下面提供常见对象的转化。

  1.  GDI+的Bitmap转换为GDI的CBitmap:(核心部分是利用Bitmap类的成员函数GetHBITMAP获得图像的基本信息)

     //已有的Bitmap对象pBitmap,以及CDC对象pDC

     CBitmap* bmp;

     CDC   m_dcBmp;

     m_dcBmp.CreateCompatibleDC(&pDC); 
     HBITMAP hBitmap;
     pBitmap->GetHBITMAP(Color(0,0,0),&hBitmap);//占用内存较多,
     bmp= CBitmap::FromHandle(hBitmap);

     m_dcBmp.SelectObject(bmp);//bmp对象获得了pBitmap的所有信息,CBitmap对象对应的设备为m_dcBmp

  2.  GDI的CBitmap转换为GDI+的Bitmap:(核心部分是利用Bitmap类的构造函数Bitmap::Bitmap(HBITMAP,HPALETTE)获得CBitmap对象图像的基本信息) 

     CBitmap* bmp=m_dcbmp.GetCurrentBitmap();
     HBITMAP  bmp_hbitmap=(HBITMAP)(*bmp);
      Bitmap   m_pBmp(bmp_hbitmap,NULL); 

首先通过MSDN文档查得Bitmap是Image的子类,所以我们用Bitmap来实现,最后强制把Bitmap转成Image。看到网上有不少的人在问,好像答案挺少的。在这里贴出来,仅两行代码就可以实现喽。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void BitmapToImage(CBitmap *pBitmap,Image* &img)  
  2. {  
  3.     //拿到位图的句柄 Bitmap是Image的子类  
  4.     HBITMAP  hBmp = (HBITMAP)pBitmap->GetSafeHandle();  
  5.     //创建一个从位图句柄的Bitmap位图  
  6.     img = new Bitmap(hBmp,NULL);  
  7. }  
  1. 下午在网上找了很久关于把资源文件中的位图导入到gdi+的Bitmap对象中的方法,但是网上的方法不是要写大段的代码,就是根本无法实现预期目标。最后通过我自己的尝试发现了一个简单易用的方法。就是先把位图导入到一个gdi对象CBitmap中然后通过其句柄加载到gdi+的Bitmap对象中。代码如下:  
  2.   
  3. CBitmap bmp;  
  4.   
  5. bmp.LoadBitmap(IDB_BITMAP1);  
  6.   
  7. Bitmap bitmap((HBITMAP)bmp);  
  8.   
  9. 仅三行代码就够了!  


有了HBITMAP句柄和BITMAP,怎样操作位图数据?

2013-05-04 13:04 AAMINI4    分类:VC++  |  浏览 824 次
  软件 编程语言
HBITMAP hBitmap;
BITMAP  m_bmp;
GetObject(hBitmap,sizeof(m_bmp),&m_bmp);
现在怎样修改位图数据?
2013-05-04 19:41 提问者采纳
哦你拿到HBITMAP了啊。

下一步你该看GetDIBits函数了

p.s. 我自己的话用的是gdi+不是gdi,所以GetDIBits其实我不熟
gdi+里面拿到Bitmap对象以后是调用LockBits的

### 回答1: 以下是 MFC 将一张 24 位图转换成单色位图的代码,其中使用了 GDI+ 库: 1. 首先需要添加头文件: ```cpp #include <afxwin.h> #include <afxwinapp.h> #include <afxwin.h> #include <afxext.h> #include <afxdisp.h> #include <afxdtctl.h> #include <afxcmn.h> #include <afxcontrolbars.h> #include <gdiplus.h> using namespace Gdiplus; ``` 2. 然后定义一个函数来进行转换: ```cpp void ConvertToMonoBitmap(CBitmap& bmpSrc, CBitmap& bmpDest) { // 获取源图像的宽度和高度 BITMAP bmpInfo; bmpSrc.GetBitmap(&bmpInfo); int width = bmpInfo.bmWidth; int height = bmpInfo.bmHeight; // 创建 GDI+ Bitmap 对象 Bitmap* pBitmap = Bitmap::FromHBITMAP(bmpSrc, NULL); // 创建 GDI+ Graphics 对象 Graphics* pGraphics = Graphics::FromImage(pBitmap); // 创建 GDI+ Bitmap 对象,用于存储转换后的图像 Bitmap* pMonoBitmap = new Bitmap(width, height); // 创建 GDI+ Graphics 对象,用于绘制转换后的图像 Graphics* pMonoGraphics = Graphics::FromImage(pMonoBitmap); // 创建 GDI+ SolidBrush 对象,用于绘制黑色和白色 SolidBrush brushBlack(Color(0, 0, 0)); SolidBrush brushWhite(Color(255, 255, 255)); // 遍历源图像的每个像素 for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // 获取源图像该像素的颜色值 Color color; pBitmap->GetPixel(x, y, &color); // 计算灰度值 int gray = (color.GetR() + color.GetG() + color.GetB()) / 3; // 绘制单色位图 if (gray > 128) pMonoGraphics->FillRectangle(&brushWhite, x, y, 1, 1); else pMonoGraphics->FillRectangle(&brushBlack, x, y, 1, 1); } } // 将转换后的图像保存到目标位图中 bmpDest.Attach((HBITMAP)pMonoBitmap->GetHBITMAP(Color(), NULL)); // 释放资源 delete pBitmap; delete pGraphics; delete pMonoBitmap; delete pMonoGraphics; } ``` 3. 在需要进行转换的地方调用该函数即可: ```cpp // 加载源图像 CBitmap bmpSrc; bmpSrc.LoadBitmap(IDB_BITMAP_SRC); // 创建目标位图 CBitmap bmpDest; bmpDest.CreateBitmap(100, 100, 1, 1, NULL); // 转换图像 ConvertToMonoBitmap(bmpSrc, bmpDest); // 显示目标图像 CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_DEST); pStatic->SetBitmap(bmpDest); ``` ### 回答2: 在 MFC 中将一张24位图转换成单色位图的代码如下: ```cpp CImage sourceImage; CImage targetImage; // 1. 加载原始图像 sourceImage.Load(_T("source.bmp")); // 2. 获取原始图像的宽度和高度 int width = sourceImage.GetWidth(); int height = sourceImage.GetHeight(); // 3. 创建目标图像,与原始图像大小相同,像素格式为单色位图 targetImage.Create(width, height, 1); // 4. 遍历原始图像的每个像素 for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // 5. 获取原始图像当前像素的 RGB 值 COLORREF rgb = sourceImage.GetPixel(x, y); BYTE red = GetRValue(rgb); BYTE green = GetGValue(rgb); BYTE blue = GetBValue(rgb); // 6. 根据灰度值计算目标图像当前像素的亮度值 BYTE brightness = static_cast<BYTE>(0.299 * red + 0.587 * green + 0.114 * blue); // 7. 将亮度值设置为目标图像当前像素的颜色 targetImage.SetPixel(x, y, RGB(brightness, brightness, brightness)); } } // 8. 保存目标图像为单色位图 targetImage.Save(_T("target.bmp")); ``` 以上代码首先加载一张24位的原始图像,然后创建一个与原始图像大小相同的单色位图。然后遍历原始图像的每个像素,获取其 RGB 值,然后根据灰度公式计算目标图像当前像素的亮度值。最后将亮度值设置为目标图像当前像素的颜色。最终,将目标图像保存为单色位图。 ### 回答3: 要将一张24位图转换成单色位图,可以使用以下代码: 首先,我们需要创建一个CImage对象,并加载原始的24位图像文件: CImage originalImage; originalImage.Load(_T("原始图像路径")); 接下来,我们创建一个与原始图像大小相同的单色位图对象,并设置其宽度、高度以及像素格式: CImage monoImage; monoImage.Create(originalImage.GetWidth(), originalImage.GetHeight(), originalImage.GetBPP()); 然后,我们需要遍历每个像素,将其转换为单色位图的像素值。对于24位图像,每个像素由红、绿、蓝三个颜色分量组成,我们可以使用GetPixel和SetPixel函数分别获取和设置像素值: for (int y = 0; y < originalImage.GetHeight(); y++) { for (int x = 0; x < originalImage.GetWidth(); x++) { COLORREF color = originalImage.GetPixel(x, y); // 将彩色像素转换为灰度值 int grayValue = (GetRValue(color) + GetGValue(color) + GetBValue(color)) / 3; // 设置单色位图像素值(黑白二值化) if (grayValue > 128) monoImage.SetPixel(x, y, RGB(255, 255, 255)); // 白色 else monoImage.SetPixel(x, y, RGB(0, 0, 0)); // 黑色 } } 最后,我们保存转换后的单色位图到指定文件路径,并释放原始图像资源: monoImage.Save(_T("单色位图路径")); originalImage.Destroy(); 以上是将一张24位图转换成单色位图的代码。其中,通过对彩色像素进行灰度化处理,并根据阈值将像素值设为黑色或白色,实现了单色位图的生成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值