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 } 

    还未测试~先放这儿

  • 相关阅读:
    树(三)——自平衡二叉树(AVL)
    树(二)——二叉树
    10. IDENTITY属性使用小结
    09. 约束与索引的联系
    08. 删除重复&海量数据
    07. 分页写法小结
    06. 父子节点(树)遍历写法小结
    01. SQL Server 如何读写数据
    05. 取SQL分组中的某几行数据
    04. 字符串合并与拆分写法小结
  • 原文地址:https://www.cnblogs.com/xzy1210/p/3622818.html
Copyright © 2011-2022 走看看