2017-10-08 58 views
-1

由於通用Windows平臺默認不支持平面化位圖「圖層」,因此我一直在創建算法(基於發現的一個算法here)以獲取每個圖層的每個單獨像素,並將它們疊加在另一個上。問題是,因爲我使用Alpha來允許圖像具有透明像素,所以我不確定如何正確地合併像素,使其看起來好像一個位於另一個之上。如何在C#UWP中使用原始像素數據合併圖層?

這是到目前爲止我的代碼:

private unsafe SoftwareBitmap CompileImage() 
    { 
     SoftwareBitmap softwareBitmap = new SoftwareBitmap(BitmapPixelFormat.Bgra8, Width, Height); 

     using (BitmapBuffer buffer = softwareBitmap.LockBuffer(BitmapBufferAccessMode.Write)) 
     { 
      using (var reference = buffer.CreateReference()) 
      { 
       byte* dataInBytes; 
       uint capacity; 
       ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity); 

       BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0); 

       for (int index = 0; index < layers.Length; index++) 
       { 
        for (int i = 0; i < bufferLayout.Height; i++) 
        { 
         for (int j = 0; j < bufferLayout.Width; j++) 
         { 
          if(index == 0) 
          { 
           dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 0] = 
            layers[index].pixelData[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 0]; //B 
           dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 1] = 
            layers[index].pixelData[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 1]; //G 
           dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 2] = 
            layers[index].pixelData[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 2]; //R 
           dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 3] = 
            layers[index].pixelData[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 3]; //A 
          } 
          else if(index > 0) 
          { 

           //Attempts to "Average" pixel data 
           dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 0] = 
            (byte)(dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 0] * 
            layers[index].pixelData[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 0]/2); 
           dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 1] = 
            (byte)(dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 1] * 
            layers[index].pixelData[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 1]/2); 
           dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 2] = 
            (byte)(dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 2] * 
            layers[index].pixelData[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 2]/2); 
           dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 3] = 
            (byte)(dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 3] * 
            layers[index].pixelData[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 3]/2); 
          } 
         } 
        } 
       } 
      } 
     } 
     return softwareBitmap; 
    } 

目前的算法將每個像素的平均BGRA值在每一層,並返回結果。這不是我打算做的。我如何去糾正它?在此先感謝

+0

我仍然試圖瞭解我在做什麼我的帖子錯了。很顯然,如果我繼續得到如此多的降薪,儘管按照規則建議我對待我的問題所做的一切,我正在做一些錯誤-_- – Dylanrules22

回答

0

要應用一個alpha混合你乘以逆alpha和當前顏色的alpha,當然你應該做一個0-1的規模(這就是爲什麼圖形卡與浮動顏色)。

每例如,假設有三個層,A,B和C中,使用A作爲鹼,然後將其與乙混合:(僞碼)

//bAlpha is thge alpha value of the current pixel from B in byte value 
var alpha = bAlpha/255.0f; 
var invAlpha = 1.0f - alpha; 

//aRGB is the RGB value of the pixel on the layer A 
//bRGB is the RGB value of the pixel on the layer B 
var abRGB = aRGB * invAlpha + bRGB * alpha; 

現在應用的第三層:

//cAlpha is thge alpha value of the current pixel from C in byte value 
alpha = cAlpha/255.0f; 
invAlpha = 1.0f - alpha; 

//abRGB is the RGB value of the previously mixed layers 
//cRGB is the RGB value of the pixel on the layer C 
var abcRGB = abRGB * invAlpha + cRGB * alpha; 

當然,所有這一切都是在ARGB模式,這裏還有pARGB其中顏色已經預乘,所以你只需要乘以先前的顏色由逆α和添加當前顏色。

//bAlpha is the alpha value of the current pixel from B in byte value 
var invAlpha = 1.0f - (bAlpha/255.0f); 

//aRGB is the RGB value of the pixel on the layer A 
//bRGB is the RGB value of the pixel on the layer B 
var abRGB = aRGB * invAlpha + bRGB; 

invAlpha = 1.0f - (cAlpha/255.0f); 

//abRGB is the RGB value of the previously mixed layers 
//cRGB is the RGB value of the pixel on the layer C 
var abcRGB = abRGB * invAlpha + cRGB; 
相關問題