<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      厚積薄發
      海納百川,有容乃大
      最近工作中有個需求是將Icon轉成帶Alpha通道的Bitmap, 雖然網上有不少這方面的文章,但很多都是錯的, 這里記錄下,或許對后來人有用。

      要實現這個功能,我們首先需要理解Icon的格式,我們可以看到Icon的結構如下:
      typedef struct _ICONINFO {
          BOOL fIcon;
          DWORD xHotspot;
          DWORD yHotspot;
          HBITMAP hbmMask;
          HBITMAP hbmColor;
      } ICONINFO;
      typedef ICONINFO *PICONINFO;

      從上面我們可以看到Icon和cursor的結構基本一樣,主要都包括一幅mask位圖和一幅color位圖
      如下一個8個像素的紅色小圖標:


      它的Mask位圖如下:

      如果我們把Mask位圖畫出來,我們會看到周圍1的區域都是白色的,中間0的區域是黑色的

      它的color位圖如下:

      如果我們把color位圖畫出來,我們會看到除了中間區域是紅色的,周圍0的區域都是黑色的。

      思考將Icon畫到目標位圖上時,他們是如何最終合成的?

      實際很簡單,就是先和Mask位圖做與(AND)運算,然后再與Color位圖做異或(XOR)運算: AND運算的結果是除了中間區域變成黑色(0),目標位圖的其他區域都保持不變;XOR 運算的結果是周圍區域只有和0不一樣 (color位圖)才會得到1 (也就是原來是1則保持), 中間區域因為前面經過mask運算后都是0,所以中間R部分XOR后也會保留。

      我們看到通過AND和XOR運算,我們將中間紅色部分扣出來貼了上去,而其他周圍區域保持不變, 這種方式實際上也是DrawIconExTransparentBlt的實現原理。
      理解了Icon格式,我們要將Icon轉Bitmap就好辦了, 我們只要將Color位圖考出來,然后位圖里將mask部分是1的部分的Alpha通道改成0就可以了。 
      這里要 注意的是有些icon 的color位圖本身就是帶Alpha通道的,這樣我們就實際上用不到Mask位圖了,也不用再去改Alpha通道了。

      另外對于黑白單色Icon( 比如黑白光標), 我們很多時候會發現它的color位圖是空的, 這種情況下所有的數據實際上都存到了Mask位圖里,這時的Mask位圖高度是Icon高度的2倍,上半部分是mask部分,下班部分保存了color位圖部分。

      最后簡單貼下代碼:

      HBITMAP IconToBitmap(HICON hIcon, SIZE* pTargetSize = NULL)
      {
          ICONINFO info = {0};
          
      if(hIcon == NULL
              
      || !GetIconInfo(hIcon, &info)
              
      || !info.fIcon)
          {
              
      return NULL;
          }

          INT nWidth = 0;
          INT nHeight = 0;
          
      if(pTargetSize != NULL)
          {
              nWidth = pTargetSize->cx;
              nHeight = pTargetSize->cy;
          }
          
      else
          {
              
      if(info.hbmColor != NULL)
              {
                  BITMAP bmp = {0};
                  GetObject(info.hbmColor, sizeof(bmp), &bmp);

                  nWidth = bmp.bmWidth;
                  nHeight = bmp.bmHeight;
              }
          }

        if(info.hbmColor != NULL)
       {
           DeleteObject(info.hbmColor);
          info.hbmColor = NULL;
        }
       
        if(info.hbmMask != NULL)
       {
            DeleteObject(info.hbmMask);
            info.hbmMask = NULL;
       }
       
          if(nWidth <= 0
              
      || nHeight <= 0)
          {
              
      return NULL;
          }

          INT nPixelCount = nWidth * nHeight;

          HDC dc = GetDC(NULL);
          INT* pData = NULL;
          HDC dcMem = NULL;
          HBITMAP hBmpOld = NULL;
          
      bool* pOpaque = NULL;
          HBITMAP dib = NULL;
          BOOL bSuccess = FALSE;

          
      do
          {
              BITMAPINFOHEADER bi = {0};
              bi.biSize = sizeof(BITMAPINFOHEADER);    
              bi.biWidth = nWidth;
              bi.biHeight = -nHeight;  
              bi.biPlanes = 1;    
              bi.biBitCount = 32;    
              bi.biCompression = BI_RGB;
              dib = CreateDIBSection(dc, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (VOID**)&pData, NULL, 0);
              
      if(dib == NULL) break;

              memset(pData, 0, nPixelCount * 4);

              dcMem = CreateCompatibleDC(dc);
              
      if(dcMem == NULL) break;

              hBmpOld = (HBITMAP)SelectObject(dcMem, dib);
              ::DrawIconEx(dcMem, 00, hIcon, nWidth, nHeight, 0, NULL, DI_MASK);

              pOpaque = new(std::nothrow) bool[nPixelCount];
              
      if(pOpaque == NULL) break;
              
      for (INT i = 0; i < nPixelCount; ++i)
              {
                  pOpaque[i] = !pData[i];
              }

              memset(pData, 0, nPixelCount * 4);
              ::DrawIconEx(dcMem, 00, hIcon, nWidth, nHeight, 0, NULL, DI_NORMAL);

              BOOL bPixelHasAlpha = FALSE;
              UINT* pPixel = (UINT*)pData;
              
      for(INT i = 0; i<nPixelCount; ++i, ++pPixel)
              {
                  
      if((*pPixel & 0xff000000!= 0)
                  {
                      bPixelHasAlpha = TRUE;
                      
      break;
                  }
              }

              
      if(!bPixelHasAlpha)
              {
                  pPixel = (UINT*)pData;
                  
      for(INT i=0;i <nPixelCount; ++i, ++pPixel)
                  {
                      
      if(pOpaque[i])
                      {
                          
      *pPixel |= 0xFF000000;
                      }
                      
      else
                      {
                          
      *pPixel &= 0x00FFFFFF;
                      }
                  }
              }

              bSuccess = TRUE;

          } while(FALSE);


          
      if(pOpaque != NULL)
          {
              delete []pOpaque;
              pOpaque = NULL;
          }

          
      if(dcMem != NULL)
          {
       
             SelectObject(dcMem, hBmpOld);
              DeleteDC(dcMem);
          }

          ReleaseDC(NULL, dc);

          
      if(!bSuccess)
          {
              
      if(dib != NULL)
              {
                  DeleteObject(dib);
                  dib = NULL;
              }
          }

          
      return dib;
      }

      另外感慨Webkit是個寶庫, 我們的Icon轉Bitmap代碼實際上可以參考這里:
      posted on 2014-08-21 23:40  Richard Wei  閱讀(3067)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 老司机精品影院一区二区三区| 亚洲国产在一区二区三区| 又粗又紧又湿又爽的视频| 亚洲av男人电影天堂热app| free性开放小少妇| 久久69国产精品久久69软件| 好紧好滑好湿好爽免费视频| 人妻无码久久久久久久久久久| 色综合亚洲一区二区小说| 免费无码肉片在线观看| 国产成人久久蜜一区二区| 最新国内精品自在自线视频| 久久午夜无码鲁丝片直播午夜精品| 欧美性猛交xxxx免费看| 久久天天躁狠狠躁夜夜躁2o2o | 日韩少妇内射免费播放| 国产微拍一区二区三区四区| 亚洲国产欧美在线看片一国产| 亚洲av无码专区在线亚| 国产太嫩了在线观看| 亚洲成片在线看一区二区| a片在线免费观看| 国产成人拍国产亚洲精品| 国产成人毛片无码视频软件| 亚洲一区二区三区在线观看精品中文 | jizz视频在线观看| 老熟女重囗味hdxx69| 日本高清免费不卡视频| 日韩毛片在线视频x| 久久国产精品久久精品国产| 成人激情视频一区二区三区| 一区二区乱子伦在线播放| 亚洲熟女乱色综合亚洲图片| 在线看高清中文字幕一区| 乱中年女人伦av二区| 国日韩精品一区二区三区| 亚洲成人av综合一区| 界首市| 久久永久视频| 亚洲欧洲中文日韩久久av乱码| 丁香五月亚洲综合在线国内自拍|