如何从GDI设备上下文中获取32bpp位图/图像? [英] How to get a 32bpp bitmap/image from a GDI Device Context?

查看:290
本文介绍了如何从GDI设备上下文中获取32bpp位图/图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用此项目的代码


  1. 正在使用第一个代码段绘制按钮图片



正如您所看到的GDI 24bpp不能请参阅对话框背景。它只是假定纯黑色背景。只有GDI +才能看到它。但是我找不到一个从 Gdiplus :: Graphics 对象中获取位图的方法。



我可以得到一个32bpp的背景备份,以便正确地绘制我的透明图像吗?



使用没有备份图像导致GDI +的alpha混合模糊背景越来越多

解决方案

经过3天的摸索,我通过测试发现了一些东西。这实际上可以通过方便更容易和32bpp渲染来完成!

  //获取客户区父代
CRect Rect;
GetWindowRect(& Rect);
CWnd * pParent = GetParent();
ASSERT(pBarent);
pParent-> ScreenToClient(& Rect);

//获取父级DC
CDC * parentDC = pParent-> GetDC();

// GDI代码(只支持24bpp)
// CDC MemDC;
// CBitmap bmp;
//MemDC.CreateCompatibleDC(parentDC);
//bmp.CreateCompatibleBitmap(parentDC,Rect.Width(),Rect.Height());
// CBitmap * pOldBmp = MemDC.SelectObject(& bmp);
//MemDC.BitBlt(0,0,Rect.Width(),Rect.Height(),parentDC,Rect.left,Rect.top,SRCCOPY);
//MemDC.SelectObject(pOldBmp);

// GDI + 32 bpp支持的代码(这里是重要的更改)
Bitmap * bmp = new Bitmap(Rect.Width(),Rect.Height());
Graphics bmpGraphics(bmp);
HDC hBmpDC = bmpGraphics.GetHDC();
BitBlt(hBmpDC,0,0,Rect.Width(),Rect.Height(),parentDC-> GetSafeHdc(),Rect.left,Rect.top,SRCCOPY); // BitBlt实际上能够做32bpp blts

//释放DCs
bmpGraphics.ReleaseDC(hBmpDC);
pParent-> ReleaseDC(parentDC);

在这里! 4行代码,你得到一个32bpp Gdiplus :: Bitmap!您可以稍后在 OnEraseBkgnd 中绘制:

 区域
CRect rect;
GetClientRect(& rect);

//将复制的背景绘制回父代
Graphics gr(* pDC);
gr.DrawImage(bmp,0,0,rect.Width(),rect.Height());

请注意,Bitmap应该是一个成员变量,它也必须释放对控制的破坏。


I am using code from this Project http://www.codeproject.com/Articles/9064/Yet-Another-Transparent-Static-Control in order to draw transparent button images from my subclassed Button control onto my CDialogEx.

This code is meant for legacy 24bpp GDI functions:

BOOL CTransparentStatic2::OnEraseBkgnd(CDC* pDC)
{
   if (m_Bmp.GetSafeHandle() == NULL)
   {
      CRect Rect;
      GetWindowRect(&Rect);
      CWnd *pParent = GetParent();
      ASSERT(pParent);
      pParent->ScreenToClient(&Rect); //convert our corrdinates to our parents

      //copy what's on the parents at this point
      CDC *pDC = pParent->GetDC();
      CDC MemDC;
      MemDC.CreateCompatibleDC(pDC);
      m_Bmp.CreateCompatibleBitmap(pDC,Rect.Width(),Rect.Height());
      CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);

      MemDC.BitBlt(0,0,Rect.Width(),Rect.Height(),pDC,Rect.left,Rect.top,SRCCOPY);

      MemDC.SelectObject(pOldBmp);

      pParent->ReleaseDC(pDC);
   }
   else //copy what we copied off the parent the first time back onto the parent
   {
      CRect Rect;
      GetClientRect(Rect);
      CDC MemDC;
      MemDC.CreateCompatibleDC(pDC);
      CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);
      pDC->BitBlt(0,0,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY);
      MemDC.SelectObject(pOldBmp);
   }

   return TRUE;
}

However the background of my CDialogEx is being drawn with GDI+ 32bpp rendering like this:

BOOL CParentDialogEx::OnEraseBkgnd(CDC* pDC)
{
   // Get GDI+ Graphics for the current Device Context
   Graphics gr(*pDC);

   // Get the client area
   CRect clientRect;
   GetClientRect(&clientRect);

   // Draw the dialog background
   // PLEASE NOTE: m_imgDlgBkgnd is a Gdiplus::Image with PNG format ==> 32bpp Image
   gr.DrawImage(m_imgDlgBkgnd, 0, 0, clientRect.Width(), clientRect.Height());
}

This causes the first code snippet to make a backup of a black rectangle instead of the 32bpp drawn content to it. This again causes my button control to always have a black background.

To make my problem clear, please see the pictures below:

  1. Button images are being drawn onto the CDialogEx background (normally):

  1. Button images are being drawn with the first code snippet

As you can see GDI 24bpp cannot see the dialog background. It just assumes plain black background. Only GDI+ could see it. However I was not able to find a way to get a bitmap from a Gdiplus::Graphics object.

How can I get a 32bpp background backup in order to draw my transparent images correctly?

Using no backup images at all causes the alpha blending of GDI+ to blur the background more and more on every draw.

解决方案

After 3 days of figuring around I found something by testing. This can actually be done way easier and with 32bpp rendering!

// Get the client area on the parent
CRect Rect;
GetWindowRect(&Rect);
CWnd *pParent = GetParent();
ASSERT(pParent);
pParent->ScreenToClient(&Rect);

// Get the Parent's DC
CDC *parentDC = pParent->GetDC();

// GDI Code (only 24bpp support)
//CDC MemDC;
//CBitmap bmp;
//MemDC.CreateCompatibleDC(parentDC);
//bmp.CreateCompatibleBitmap(parentDC,Rect.Width(),Rect.Height());
//CBitmap *pOldBmp = MemDC.SelectObject(&bmp);
//MemDC.BitBlt(0,0,Rect.Width(),Rect.Height(),parentDC,Rect.left,Rect.top,SRCCOPY);
//MemDC.SelectObject(pOldBmp);

// GDI+ Code with 32 bpp support (here comes the important change)
Bitmap* bmp = new Bitmap(Rect.Width(), Rect.Height());
Graphics bmpGraphics(bmp);
HDC hBmpDC = bmpGraphics.GetHDC();
BitBlt(hBmpDC, 0, 0, Rect.Width(), Rect.Height(), parentDC->GetSafeHdc(), Rect.left, Rect.top, SRCCOPY); // BitBlt is actually capable of doing 32bpp blts

// Release DCs
bmpGraphics.ReleaseDC(hBmpDC);
pParent->ReleaseDC(parentDC);

Here you go! 4 lines of code and you get a 32bpp Gdiplus::Bitmap! Which you can draw later on in OnEraseBkgnd:

// Get client Area
CRect rect;
GetClientRect(&rect);

// Draw copied background back onto the parent
Graphics gr(*pDC);
gr.DrawImage(bmp, 0, 0, rect.Width(), rect.Height());

Please note that the Bitmap should be a member variable for performance increase. It also has to be freed on the controls destruction.

这篇关于如何从GDI设备上下文中获取32bpp位图/图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆