Windows Mobile下畫透明PNG圖片的解決方案

來源:互聯網
上載者:User

CoCreateInstance建立IImagingFactory, 然後用CreateImageFromFile建立IImage的介面,最後把這個IImage用draw的介面畫到DC.但是問題在於這個Draw是沒有設定transparent屬性的? 這個東西應該如何操作呢? 在網上看到了一個解決方案. 就是把這個png圖片轉化成一張32位的bitmap,然後再透明的畫到DC上.這裡有一段調試成功的代碼:

view plaincopy to clipboardprint?
HBITMAP LoadPngImage2 (HDC hdc, LPCTSTR filename)  
{  
    IImagingFactory* pImageFactory = 0;  
    IImage* pImage = 0;  
    ImageInfo imageInfo;  
    CoInitializeEx(0, COINIT_MULTITHREADED);  
    HBITMAP hBitmap = 0;  
    LPBYTE lpByte;  
    if (SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory, 0, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void**)&pImageFactory)))  
    {  
        if (SUCCEEDED(pImageFactory->CreateImageFromFile(filename, &pImage))&& SUCCEEDED(pImage->GetImageInfo(&imageInfo)))  
        {  
            HDC bmpDC = CreateCompatibleDC(hdc);  
            //LPBYTE lpByte;  
            BITMAPINFO *pbinfo ;  
            pbinfo = (BITMAPINFO *)calloc(1, sizeof(BITMAPINFO) + 4 * sizeof(INT)) ;  
            if(!pbinfo)  
                return FALSE ;  
            pbinfo->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);  
            pbinfo->bmiHeader.biWidth = imageInfo.Width ;  
            pbinfo->bmiHeader.biHeight = imageInfo.Height ;  
            pbinfo->bmiHeader.biPlanes = 1;  
            pbinfo->bmiHeader.biBitCount = 32;  
            pbinfo->bmiHeader.biCompression = BI_ALPHABITFIELDS;  
            pbinfo->bmiHeader.biSizeImage = 0 ;  
            pbinfo->bmiHeader.biXPelsPerMeter = 11811;  
            pbinfo->bmiHeader.biYPelsPerMeter = 11811;  
            pbinfo->bmiHeader.biClrUsed = 0;  
            pbinfo->bmiHeader.biClrImportant = 0;  
            int *pMask = (int*)&(pbinfo->bmiColors[0]) ;  
            *pMask++ = 0x00FF0000 ;  
            *pMask++ = 0x0000FF00 ;  
            *pMask++ = 0x000000FF ;  
            *pMask++ = 0xFF000000 ;  
            hBitmap = CreateDIBSection(NULL, pbinfo, DIB_RGB_COLORS, (void **)&lpByte, NULL, 0) ;  
            free(pbinfo) ;  
            if(!hBitmap || !lpByte)  
                return FALSE ;  
            RECT rect = {0, 0, imageInfo.Width, imageInfo.Height};  
            IBitmapImage *pBitmapImage;  
            BitmapData bitmapData;  
            bitmapData.Width = imageInfo.Width;  
            bitmapData.Height = imageInfo.Height;  
            bitmapData.PixelFormat = imageInfo.PixelFormat;  
            pBitmapImage = NULL;  
            pImageFactory->CreateBitmapFromImage(pImage, imageInfo.Width, imageInfo.Height, PIXFMT_32BPP_ARGB,  
                InterpolationHintDefault, &pBitmapImage);  
            pBitmapImage->LockBits(&rect, ImageLockModeRead,PIXFMT_32BPP_ARGB, &bitmapData);  
            //transferring the pixels  
            memcpy(lpByte, bitmapData.Scan0, imageInfo.Width * imageInfo.Height * 4);  
            pBitmapImage->UnlockBits(&bitmapData);  
            pBitmapImage->Release();  
            pImage->Release();  
            DeleteDC(bmpDC);  
        }  
        pImageFactory->Release();  
    }  
    CoUninitialize();  
    //ProcessThePixelsWithAlphaChannel Here       
    // vertical flip and ProcessThePixelsWithAlphaChannel here  
    for (UINT y=0; y<imageInfo.Height/2; y++)  
    {  
        BYTE * pPixel = (BYTE *) lpByte + imageInfo.Width * 4 * y;  
        BYTE * pDstPixel = (BYTE*) lpByte + imageInfo.Width * 4 * (imageInfo.Height-y-1);   
        for (UINT x=0; x<imageInfo.Width; x++)  
        {  
            pPixel[0] = pPixel[0] * pPixel[3] / 255;  
            pPixel[1] = pPixel[1] * pPixel[3] / 255;  
            pPixel[2] = pPixel[2] * pPixel[3] / 255;  
            pDstPixel[0] = pDstPixel[0] * pDstPixel[3] / 255;  
            pDstPixel[1] = pDstPixel[1] * pDstPixel[3] / 255;  
            pDstPixel[2] = pDstPixel[2] * pDstPixel[3] / 255;  
            INT* pOrigin = (INT*)pPixel;  
            INT* pDst    = (INT*)pDstPixel;  
            INT temp = *pOrigin;  
            *pOrigin = *pDst;  
            *pDst = temp;  
            pPixel += 4;  
            pDstPixel += 4;  
        }  
    }  
    return hBitmap;  

HBITMAP LoadPngImage2 (HDC hdc, LPCTSTR filename)
{
 IImagingFactory* pImageFactory = 0;
 IImage* pImage = 0;
 ImageInfo imageInfo;
 CoInitializeEx(0, COINIT_MULTITHREADED);
 HBITMAP hBitmap = 0;
 LPBYTE lpByte;
 if (SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory, 0, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void**)&pImageFactory)))
 {
  if (SUCCEEDED(pImageFactory->CreateImageFromFile(filename, &pImage))&& SUCCEEDED(pImage->GetImageInfo(&imageInfo)))
  {
   HDC bmpDC = CreateCompatibleDC(hdc);
   //LPBYTE lpByte;
   BITMAPINFO *pbinfo ;
   pbinfo = (BITMAPINFO *)calloc(1, sizeof(BITMAPINFO) + 4 * sizeof(INT)) ;
   if(!pbinfo)
    return FALSE ;
   pbinfo->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
   pbinfo->bmiHeader.biWidth = imageInfo.Width ;
   pbinfo->bmiHeader.biHeight = imageInfo.Height ;
   pbinfo->bmiHeader.biPlanes = 1;
   pbinfo->bmiHeader.biBitCount = 32;
   pbinfo->bmiHeader.biCompression = BI_ALPHABITFIELDS;
   pbinfo->bmiHeader.biSizeImage = 0 ;
   pbinfo->bmiHeader.biXPelsPerMeter = 11811;
   pbinfo->bmiHeader.biYPelsPerMeter = 11811;
   pbinfo->bmiHeader.biClrUsed = 0;
   pbinfo->bmiHeader.biClrImportant = 0;
   int *pMask = (int*)&(pbinfo->bmiColors[0]) ;
   *pMask++ = 0x00FF0000 ;
   *pMask++ = 0x0000FF00 ;
   *pMask++ = 0x000000FF ;
   *pMask++ = 0xFF000000 ;
   hBitmap = CreateDIBSection(NULL, pbinfo, DIB_RGB_COLORS, (void **)&lpByte, NULL, 0) ;
   free(pbinfo) ;
   if(!hBitmap || !lpByte)
    return FALSE ;
   RECT rect = {0, 0, imageInfo.Width, imageInfo.Height};
   IBitmapImage *pBitmapImage;
   BitmapData bitmapData;
   bitmapData.Width = imageInfo.Width;
   bitmapData.Height = imageInfo.Height;
   bitmapData.PixelFormat = imageInfo.PixelFormat;
   pBitmapImage = NULL;
   pImageFactory->CreateBitmapFromImage(pImage, imageInfo.Width, imageInfo.Height, PIXFMT_32BPP_ARGB,
    InterpolationHintDefault, &pBitmapImage);
   pBitmapImage->LockBits(&rect, ImageLockModeRead,PIXFMT_32BPP_ARGB, &bitmapData);
   //transferring the pixels
   memcpy(lpByte, bitmapData.Scan0, imageInfo.Width * imageInfo.Height * 4);
   pBitmapImage->UnlockBits(&bitmapData);
   pBitmapImage->Release();
   pImage->Release();
   DeleteDC(bmpDC);
  }
  pImageFactory->Release();
 }
 CoUninitialize();
 //ProcessThePixelsWithAlphaChannel Here  
 // vertical flip and ProcessThePixelsWithAlphaChannel here
 for (UINT y=0; y<imageInfo.Height/2; y++)
 {
  BYTE * pPixel = (BYTE *) lpByte + imageInfo.Width * 4 * y;
  BYTE * pDstPixel = (BYTE*) lpByte + imageInfo.Width * 4 * (imageInfo.Height-y-1);
  for (UINT x=0; x<imageInfo.Width; x++)
  {
   pPixel[0] = pPixel[0] * pPixel[3] / 255;
   pPixel[1] = pPixel[1] * pPixel[3] / 255;
   pPixel[2] = pPixel[2] * pPixel[3] / 255;
   pDstPixel[0] = pDstPixel[0] * pDstPixel[3] / 255;
   pDstPixel[1] = pDstPixel[1] * pDstPixel[3] / 255;
   pDstPixel[2] = pDstPixel[2] * pDstPixel[3] / 255;
   INT* pOrigin = (INT*)pPixel;
   INT* pDst    = (INT*)pDstPixel;
   INT temp = *pOrigin;
   *pOrigin = *pDst;
   *pDst = temp;
   pPixel += 4;
   pDstPixel += 4;
  }
 }
 return hBitmap;
}
 

類似的源碼可以在MSDN論壇的某一個文章中找到.但是不是非常完整且正確. 這裡做了一些修正. 略去之前的那些過程,但看最後的這個for迴圈, 實際上做了一個垂直方向的180度翻轉. 這就是說這裡的介面memcpy拷貝過去的圖片像素資訊實際上是被翻轉過的, 這個在很多camera的幀裡面都有體現.

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/hhygcy/archive/2009/04/29/4138195.aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.