zoukankan      html  css  js  c++  java
  • UpdateLayeredWindow后,使用Gdi DrawText文字透明的解决办法

    来源:http://stackoverflow.com/questions/5309914/updatelayeredwindow-and-drawtext

    要点就是在先在memDc DrawText,然后手动设置DIB的Alpha值,最后通过AlphaBlend贴到DC。

    Question:

    I'm using UpdateLayeredWindow to display an application window. I have created my own custom buttons and i would like to create my own static text. The problem is that when i try to draw the text on the hdc, the DrawText or TextOut functions overwrite the alpha channel of my picture and the text will become transparent. I tried to find a solution to this but i could not find any. My custom controls are designed in such way that they will do all the drawing in a member function called Draw(HDC hDc), so they can only access the hdc. I would like to keep this design. Can anyone help me? I am using MFC and i would want to achieve the desired result without the use of GDI+.

    Answer:

    I know this is an old post ... but I just had this very same problem ... and it was driving me CRAZY.

    Eventually, I stumbled upon this post by Mike Sutton to the microsoft.public.win32.programmer.gdi newsgroup ... from almost 7 years ago!

    Basically, the DrawText (and TextOut) do not play nicely with the alpha channel and UpdateLayeredWindow ... and you need to premultiply the R, G, and B channels with the alpha channel.

    In Mike's post, he shows how he creates another DIB (device independent bitmap) upon which he draws the text ... and alpha blends that into the other bitmap.

    After doing this, my text looked perfect!

    Just in case, the link to the newsgroup post dies ... I am going to include the code here. All credit goes to Mike Sutton (@mikedsutton).

    Here is the code that creates the alpha blended bitmap with the text on it:

     1 HBITMAP CreateAlphaTextBitmap(LPCSTR inText, HFONT inFont, COLORREF inColour)
     2 { 
     3     int TextLength = (int)strlen(inText); 
     4     if (TextLength <= 0) return NULL; 
     5 
     6     // Create DC and select font into it 
     7     HDC hTextDC = CreateCompatibleDC(NULL); 
     8     HFONT hOldFont = (HFONT)SelectObject(hTextDC, inFont); 
     9     HBITMAP hMyDIB = NULL; 
    10 
    11     // Get text area 
    12     RECT TextArea = {0, 0, 0, 0}; 
    13     DrawText(hTextDC, inText, TextLength, &TextArea, DT_CALCRECT); 
    14     if ((TextArea.right > TextArea.left) && (TextArea.bottom > TextArea.top))
    15     { 
    16         BITMAPINFOHEADER BMIH; 
    17         memset(&BMIH, 0x0, sizeof(BITMAPINFOHEADER)); 
    18         void *pvBits = NULL; 
    19 
    20         // Specify DIB setup 
    21         BMIH.biSize = sizeof(BMIH); 
    22         BMIH.biWidth = TextArea.right - TextArea.left; 
    23         BMIH.biHeight = TextArea.bottom - TextArea.top; 
    24         BMIH.biPlanes = 1; 
    25         BMIH.biBitCount = 32; 
    26         BMIH.biCompression = BI_RGB; 
    27 
    28         // Create and select DIB into DC 
    29         hMyDIB = CreateDIBSection(hTextDC, (LPBITMAPINFO)&BMIH, 0, (LPVOID*)&pvBits, NULL, 0); 
    30         HBITMAP hOldBMP = (HBITMAP)SelectObject(hTextDC, hMyDIB); 
    31         if (hOldBMP != NULL)
    32         { 
    33             // Set up DC properties 
    34             SetTextColor(hTextDC, 0x00FFFFFF); 
    35             SetBkColor(hTextDC, 0x00000000); 
    36             SetBkMode(hTextDC, OPAQUE); 
    37 
    38             // Draw text to buffer 
    39             DrawText(hTextDC, inText, TextLength, &TextArea, DT_NOCLIP); 
    40             BYTE* DataPtr = (BYTE*)pvBits; 
    41             BYTE FillR = GetRValue(inColour); 
    42             BYTE FillG = GetGValue(inColour); 
    43             BYTE FillB = GetBValue(inColour); 
    44             BYTE ThisA; 
    45             for (int LoopY = 0; LoopY < BMIH.biHeight; LoopY++) { 
    46                 for (int LoopX = 0; LoopX < BMIH.biWidth; LoopX++) { 
    47                     ThisA = *DataPtr; // Move alpha and pre-multiply with RGB 
    48                     *DataPtr++ = (FillB * ThisA) >> 8; 
    49                     *DataPtr++ = (FillG * ThisA) >> 8; 
    50                     *DataPtr++ = (FillR * ThisA) >> 8; 
    51                     *DataPtr++ = ThisA; // Set Alpha 
    52                 } 
    53             } 
    54 
    55             // De-select bitmap 
    56             SelectObject(hTextDC, hOldBMP); 
    57         } 
    58     } 
    59 
    60     // De-select font and destroy temp DC 
    61     SelectObject(hTextDC, hOldFont); 
    62     DeleteDC(hTextDC); 
    63 
    64     // Return DIBSection 
    65     return hMyDIB; 
    66 }

    Here is the code that drives the CreateAlphaTextBitmap method:

     1 { 
     2     const char *DemoText = "Hello World!"; 
     3     RECT TextArea = {0, 0, 0, 0}; 
     4     HFONT TempFont = CreateFont(50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Arial"); 
     5     HBITMAP MyBMP = CreateAlphaTextBitmap(DemoText, TempFont, 0xFF); 
     6     DeleteObject(TempFont); 
     7     if (MyBMP)
     8     {
     9         // Create temporary DC and select new Bitmap into it 
    10         HDC hTempDC = CreateCompatibleDC(inDC); 
    11         HBITMAP hOldBMP = (HBITMAP)SelectObject(hTempDC, MyBMP); 
    12         if (hOldBMP)
    13         {
    14             // Get Bitmap image size
    15             BITMAP BMInf;
    16             GetObject(MyBMP, sizeof(BITMAP), &BMInf); 
    17 
    18             // Fill blend function and blend new text to window 
    19             BLENDFUNCTION bf; 
    20             bf.BlendOp = AC_SRC_OVER; 
    21             bf.BlendFlags = 0; 
    22             bf.SourceConstantAlpha = 0x80; 
    23             bf.AlphaFormat = AC_SRC_ALPHA; 
    24             AlphaBlend(inDC, inX, inY, BMInf.bmWidth, BMInf.bmHeight, hTempDC, 0, 0, BMInf.bmWidth, BMInf.bmHeight, bf); 
    25 
    26             // Clean up 
    27             SelectObject(hTempDC, hOldBMP); 
    28             DeleteObject(MyBMP); 
    29             DeleteDC(hTempDC); 
    30         } 
    31     } 
    32 } 

    还未测试~先放这儿

  • 相关阅读:
    Cocos Creator 图集 (TexturePacker、自动图集功能 、压缩纹理)
    Cocos Creator 下载不同版本引擎
    Cocos Creator 源码 (位置,阅读、修改)
    Laya3D Unity商店免费下载3D资源使用(Unity插件支持哪些导出)
    三 Laya3D 加载资源 (场景/预设/模型网格/材质/动画文件/贴图/粒子)
    二 Laya3D github demo下载并使用
    一 Laya3D Unity下载和插件安装
    AndroidUI设计之布局-详细解析布局实现
    Android 监听ScrollView的滑动
    【Android进阶】Android程序与JavaScript之间的简单调用
  • 原文地址:https://www.cnblogs.com/xzy1210/p/3622818.html
Copyright © 2011-2022 走看看