加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – Gdiplus DrawString通过远程桌面绘制透明文本

发布时间:2020-12-16 05:02:16 所属栏目:百科 来源:网络整理
导读:我正在将文本绘制到DIB部分的屏幕外位图,该位图深度为32位并使用alpha通道(ARGB).我将像素直接绘制到内存中.然后,我创建一个Gdiplus Graphics对象,将我的内存DC传递给它,并使用Graphics :: DrawString绘制文本.这在正常情况下工作正常.但是,在远程桌面上,渲
我正在将文本绘制到DIB部分的屏幕外位图,该位图深度为32位并使用alpha通道(ARGB).我将像素直接绘制到内存中.然后,我创建一个Gdiplus Graphics对象,将我的内存DC传递给它,并使用Graphics :: DrawString绘制文本.这在正常情况下工作正常.但是,在远程桌面上,渲染的文本是完全透明的,即不是绘制任何颜色像素,而是可以看到文本的位置.有谁知道为什么会这样,以及如何解决它?

这是我的drawString例程:

void SplashScreen::drawString (MyString &ivText,Gdiplus::RectF &r,Gdiplus::ARGB c,Gdiplus::StringAlignment align,Gdiplus::Font &fnt,Gdiplus::Graphics &gfx)
  {
  Gdiplus::StringFormat fmt;
  fmt.SetAlignment (align);
  Gdiplus::SolidBrush brush (c);
  wchar_t *wstr = new wchar_t [ivText.length()+1];
  std::mbstowcs (wstr,ivText.cstr(),ivText.length()+1);
  gfx.DrawString (wstr,ivText.length(),&fnt,r,&fmt,&brush);
  delete wstr;
  }

这就是我创建DIB的方式:

BITMAPV5HEADER bhd;
memset (&bhd,sizeof (bhd));
bhd.bV5Size = sizeof (BITMAPV5HEADER);
bhd.bV5Width = nWidth;
bhd.bV5Height = -nHeight;  // negative height indicates top-down DIB
bhd.bV5Planes = 1;
bhd.bV5BitCount = 32;
bhd.bV5Compression = BI_BITFIELDS;
bhd.bV5RedMask   = 0x00FF0000;
bhd.bV5GreenMask = 0x0000FF00;
bhd.bV5BlueMask  = 0x000000FF;
bhd.bV5AlphaMask = 0xFF000000; 
m_pBuf = NULL;
m_hBmp = ::CreateDIBSection (m_hDC,(BITMAPINFO *) &bhd,DIB_RGB_COLORS,(void **) &m_pBuf,NULL,0);
if (m_hBmp == NULL || m_pBuf == NULL)
   {
   // error...
   }
HGDIOBJ oldObj = ::SelectObject (m_hDC,m_hBmp);
if (oldObj == NULL)
   {
   // error...
   }

在将文本绘制到DIB之后,我做到了

gfx.Flush (Gdiplus::FlushIntentionSync);

编辑:您可能还感兴趣的是,最终绘制DIB的窗口是WS_EX_LAYERED窗口.这是一个启动画面,显示应用程序何时启动,并使用计时器和以下方法慢慢淡入淡出:

void SplashScreen::setWindowTransparency (int nAlpha)
  // @param nAlpha: 255 is opaque,0 is fully transparent.
  {
  HWND hwnd = getHwnd();
  BLENDFUNCTION blend;
  blend.BlendOp = AC_SRC_OVER;
  blend.BlendFlags = 0;
  blend.SourceConstantAlpha = nAlpha;
  blend.AlphaFormat = AC_SRC_ALPHA;
  BOOL bResult = ::UpdateLayeredWindow (hwnd,RGB (0,0),&blend,ULW_ALPHA);
  }

解决方法

我很惊讶这有用.使用gdi32绘图会丢失alpha信息,据我所知,任何使用gdi32的32位DIB上的绘图都会使DIB中的alpha信息未定义.在这种情况下,GDI必须通过gdi32,因为你给了它一个HDC.

要使用GDI绘制到RGBA DIB,您需要使用正确的像素格式(使用带有像素数据指针的构造函数,例如this one)创建由DIB内存支持的GDI Bitmap对象,然后是create a Graphics object from your Bitmap.这允许GDI直接绘制到DIB的内存并正确处理alpha通道而不是通过gdi32.

当然,如果您不需要每像素alpha,则可以通过在混合函数中使用AlphaFormat为0来简化事物,以忽略DIB中的Alpha通道.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读