【问题标题】:Manipulate WriteableBitmap Pixels操作 WriteableBitmap 像素
【发布时间】:2013-01-30 13:20:46
【问题描述】:

我正在尝试将两个图像合并为 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 Coding 书中获取了这段代码。

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

    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);
        }

   } 

【问题讨论】:

  • 据我所知,将像素直接写入 BitmapDecoder 是不可能的。顺便说一句,你为什么要这样做?您有一个 WriteableBitmap 可以在某处显示它。您可以将像素写入 BitmapEncoder 以保存位图。你还想做什么?

标签: c# windows-runtime writeablebitmap writeablebitmapex


【解决方案1】:

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.
}

【讨论】:

  • 谢谢,就是这样。但是你能告诉我如何让我的 WriteableBitmap 进入 BitmapDecoder 吗?
  • 对不起,我对WriteableBitmap 做的不多。我所看到的一切都涉及从BitmapDecoderWriteableBitmap不是WriteableBitmapBitmapDecoder。例如,stackoverflow.com/questions/14718855/…
  • 这里相同,因此问题:)
  • @Thomas - 请参阅上面的更新。它可能无法解决您的问题,但希望它能让您走得更远。祝你好运。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多