Manipulate WriteableBitmap Pixels
I'm trying to merge two images I have as WriteableBitmaps. I want to square each pixel value, add it to the other image and then take the 2nd root (+ check, if the value is above 255). As I had no luck doing so using WriteableBitmapEx and ForEach() (Sobel operator & Convolution with WriteableBitmapEx) (which also seems to be pretty slow) I tried manipulating the pixels directly using BitmapDecoder. Unfortunately I can't seem to write the Pixelstream back to a WriteableBitmap, as I get the Errors:
'Windows.Storage.Streams.IBuffer' does not contain a definition for 'AsStream' and the best extension method overload 'System.IO.WindowsRuntimeStreamExtensions.AsStream(Windows.Storage.Streams.IRandomAccessStream)' has some invalid arguments
and
Instance argument: cannot convert from 'Windows.Storage.Streams.IBuffer' to 'Windows.Storage.Streams.IRandomAccessStream'
for these lines
using (Stream stream = bmp.PixelBuffer.AsStream())
{
await stream.WriteAsync(pixels1, 0, pixels1.Length);
}
Might this be something that's broken by the WriteableBitmapEx library?
Furthermore I'm wondering how to get my WriteableBitmaps into the BitmapDecoders. I have taken this code from a Win8 Coding book.
Here's my complete code so far:
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);
}
}
IBuffer.AsStream()
is an extension method. If you want to use it, you need to include the namespace where it is defined:
using System.Runtime.InteropServices.WindowsRuntime;
Update: As I mention below in my comment, I haven't done a lot with writeable bitmaps. However, your code doesn't set the transparency value. This may at least be part of the problem:
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);
}
Should be:
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.
}
链接地址: http://www.djcxy.com/p/26884.html
上一篇: WPF RenderTargetBitmap缺少元素
下一篇: 操作WriteableBitmap像素