2014-03-25 5 views
1

현재 코드가 작은 Pbgra32 비트 맵을 더 큰 Pbgra32 비트 맵에 blit'ing합니다. 잘 작동합니다. 제가 지금하고 싶은 것은 그 작은 부분을 부분적으로 투명하게 만드는 것입니다. 이렇게하기 전에 blit 전에 작은 픽셀을 각 픽셀의 A 값에 0x7F를 쓰는 동안 RGB 값만 남겨 두어 각 픽셀을 편집해야하는 메서드로 전달합니다.알파 채널이 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가 실제로 무엇인지 깨닫고 올바르게 처리하는 것입니다 (솔루션의 주석 참조).

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) 
     { 

     } 
    } 
: 여기
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); 

는 방법 : 결과는 다음과 같이 사용할 수 있도록 이러한 방법은 수정 Pbgra32