2017-10-08 16 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

アルファミックスを適用するには、前の色に逆アルファと現在の色をアルファで掛けます。もちろん、0-1のスケールで行う必要があります(グラフィックカードは色)。 (擬似コード)

//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; 

そして今、あなたは第三の層を適用します。たとえばパー

は、あなたがして、ベースとしてAを使用Bとそれを混ぜ、あなたは三層、A、BおよびCがあるとします。もちろん

//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; 
関連する問題