我正在尝试将我拥有的两个图像合并为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);
}
}
答案 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.
}