2017-10-08 30 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; 
相关问题