操纵WriteableBitmap像素

时间:2013-02-14 16:51:34

标签: c# windows-runtime writeablebitmap writeablebitmapex

我正在尝试将我拥有的两个图像合并为WriteableBitmaps。我想对每个像素值进行平方,将其添加到另一个图像,然后取第二个根(+检查,如果值大于255)。 因为我没有运气使用WriteableBitmapEx和ForEach()(Sobel operator & Convolution with WriteableBitmapEx)(这似乎也很慢)我尝试使用BitmapDecoder直接操作像素。不幸的是,我似乎无法将Pixelstream写回WriteableBitmap,因为我得到了错误:

  

'Windows.Storage.Streams.IBuffer'不包含'AsStream'的定义和最佳扩展方法重载   'System.IO.WindowsRuntimeStreamExtensions.AsStream(Windows.Storage.Streams.IRandomAccessStream)'   有一些无效的论点

  

实例参数:无法转换   'Windows.Storage.Streams.IBuffer'来   'Windows.Storage.Streams.IRandomAccessStream'

这些行

using (Stream stream = bmp.PixelBuffer.AsStream())
{
   await stream.WriteAsync(pixels1, 0, pixels1.Length);
}

这可能是WriteableBitmapEx库破坏的东西吗?

此外,我想知道如何将WriteableBitmaps放入BitmapDecoders中。我从Win8编码书中获取了这段代码。

到目前为止,这是我的完整代码:

    async Task SobelCombine(BitmapDecoder decoder1, BitmapDecoder decoder2)
    {
        PixelDataProvider provider1 = await decoder1.GetPixelDataAsync(
            BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, new BitmapTransform(),
            ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
        byte[] pixels1 = provider1.DetachPixelData();
        PixelDataProvider provider2 = await decoder1.GetPixelDataAsync(
            BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, new BitmapTransform(),
            ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
        byte[] pixels2 = provider1.DetachPixelData();



        for (int i = 0; i < pixels1.Length; i += 4){
            pixels1[i]      = (byte)((byte)Math.Sqrt((Math.Pow(pixels1[i], 2) + Math.Pow(pixels2[i], 2))) % byte.MaxValue);
            pixels1[i + 1] =  (byte)((byte)Math.Sqrt((Math.Pow(pixels1[i + 1], 2) + Math.Pow(pixels2[i + 1], 2))) % byte.MaxValue);
            pixels1[i + 2] =  (byte)((byte)Math.Sqrt((Math.Pow(pixels1[i + 2], 2) + Math.Pow(pixels2[i + 2], 2))) % byte.MaxValue);
        }

        WriteableBitmap bmp = new WriteableBitmap((int)decoder1.OrientedPixelWidth, (int)decoder1.OrientedPixelHeight);

        using (Stream stream = bmp.PixelBuffer.AsStream())
        {
            await stream.WriteAsync(pixels1, 0, pixels1.Length);
        }

   } 

1 个答案:

答案 0 :(得分:4)

IBuffer.AsStream()是一种扩展方法。如果要使用它,则需要在命名空间中包含它:

using System.Runtime.InteropServices.WindowsRuntime;

<强>更新 正如我在下面的评论中提到的,我对可写位图没有做太多。但是,您的代码不会设置透明度值。这可能至少是问题的一部分:

for (int i = 0; i < pixels1.Length; i += 4){
    pixels1[i]      = (byte)((byte)Math.Sqrt((Math.Pow(pixels1[i], 2) + Math.Pow(pixels2[i], 2))) % byte.MaxValue);
    pixels1[i + 1] =  (byte)((byte)Math.Sqrt((Math.Pow(pixels1[i + 1], 2) + Math.Pow(pixels2[i + 1], 2))) % byte.MaxValue);
    pixels1[i + 2] =  (byte)((byte)Math.Sqrt((Math.Pow(pixels1[i + 2], 2) + Math.Pow(pixels2[i + 2], 2))) % byte.MaxValue);
}

应该是:

for (int i = 0; i < pixels1.Length; i += 4){
    pixels1[i]      = (byte)((byte)Math.Sqrt((Math.Pow(pixels1[i], 2) + Math.Pow(pixels2[i], 2))) % byte.MaxValue);
    pixels1[i + 1] =  (byte)((byte)Math.Sqrt((Math.Pow(pixels1[i + 1], 2) + Math.Pow(pixels2[i + 1], 2))) % byte.MaxValue);
    pixels1[i + 2] =  (byte)((byte)Math.Sqrt((Math.Pow(pixels1[i + 2], 2) + Math.Pow(pixels2[i + 2], 2))) % byte.MaxValue);
    pixels1[i + 3] = 255; // or some combination of the source data. 0 == completely transparent.
}