2014-03-25 40 views
1

我當前的代碼將一個小的Pbgra32位圖轉移到更大的Pbgra32位圖上。工作正常。我現在想要做的是讓那個較小的部分透明。爲此,在blit之前,我將較小的一個傳遞給應該編輯每個像素的方法,方法是在將0x7F寫入每個像素的A值時單獨保留RGB值。Alpha通道不能像WriteableBitmap一樣按預期工作

但是,我得到一個灰色的正方形,而不是50%的透明圖像。我究竟做錯了什麼?

private void MakeTransparent(ref WriteableBitmap bmp) 
    { 
     int width = bmp.PixelWidth; 
     int height = bmp.PixelHeight; 
     int stride = bmp.BackBufferStride; 
     int bytesPerPixel = (bmp.Format.BitsPerPixel + 7)/8; 

     unsafe 
     { 
      bmp.Lock(); 
      byte* pImgData = (byte*) bmp.BackBuffer; 

      int cRowStart = 0; 
      int cColStart = 0; 
      for (int row = 0; row < height; row++) 
      { 
       cColStart = cRowStart; 
       for (int col = 0; col < width; col++) 
       { 
        byte* bPixel = pImgData + cColStart; 
        UInt32* iPixel = (UInt32*) bPixel; 
        bPixel[3] = 0x7F; 
        cColStart += bytesPerPixel; 
       } 
       cRowStart += stride; 
      } 
      bmp.Unlock(); 
     } 
    } 

回答

3

我想通了。關鍵是要實現Pbgra32的真正目標並正確處理它(請參閱解決方案中的註釋)。此方法會修改一個Pbgra32使得結果可以這樣使用:

ChangeTransparency(ref wb_icon); 
var iconSize = new Size(wb_icon.PixelWidth, wb_icon.PixelHeight); 
wb_backgroundImage.Blit(new Rect(loc, iconSize), wb_icon, new Rect(iconSize), 
    WriteableBitmapExtensions.BlendMode.Alpha); 

這裏是方法:

private void ChangeTransparency(ref WriteableBitmap bmp, int newAlpha = 127) 
    { 
     try 
     { 
      int width = bmp.PixelWidth; 
      int height = bmp.PixelHeight; 
      int stride = bmp.BackBufferStride; 
      int bytesPerPixel = (bmp.Format.BitsPerPixel + 7)/8; 

      unsafe 
      { 
       bmp.Lock(); 
       byte* pImgData = (byte*)bmp.BackBuffer; 

       int cRowStart = 0; 
       int cColStart = 0; 
       for (int row = 0; row < height; row++) 
       { 
        cColStart = cRowStart; 
        for (int col = 0; col < width; col++) 
        { 
         // the RGB values are pre-multiplied by the alpha in a Pbgra32 bitmap 
         // so I need to un-pre-multiply them with the current alpha 
         // and then re-pre-multiply them by the new alpha 
         byte* bPixel = pImgData + cColStart; 

         byte A = bPixel[3]; 
         if (A > 0) 
         { 
          byte B = bPixel[0]; 
          byte G = bPixel[1]; 
          byte R = bPixel[2]; 

          bPixel[0] = Convert.ToByte((B/A)*newAlpha); 
          bPixel[1] = Convert.ToByte((G/A)*newAlpha); 
          bPixel[2] = Convert.ToByte((R/A)*newAlpha); 
          bPixel[3] = Convert.ToByte(newAlpha); 
         } 

         cColStart += bytesPerPixel; 
        } 
        cRowStart += stride; 
       } 
       bmp.Unlock(); 
      } 
     } 
     catch (Exception ex) 
     { 

     } 
    }