Stride issue with WriteableBitmap.PixelBuffer.AsStream()
-
Monday, April 09, 2012 1:13 PM
I am seeing some strange effects when manipulating pixels directly using a WriteableBitmap when I am trying to modify pixels from a loaded image vs pixels from an empty created WriteableBitmap.
When I create an empty WriteableBitmap setting pixels via the usual pixels[ (x + width * y)<<2] method works just as expected, but when I am trying to modify a PixelBuffer of a loaded image instead which has identical dimensions the same pixel setting method does set the pixels with a sheared offset and I have to manually adjust the stride by a fixed value (which varies with each loaded image file) in order to get the same result: pixels[ (x + (width + adjustment) * y)<<2]. What makes this so strange is that the length of the pixel buffer is identical in both cases.
So I suspect there might be some kind of conversion or padding going on in the Stream.write() or Stream.read() methods, but I cannot really make sense of it.
I am using the following methods to access the data:
// Read PixelBuffer from a WriteableBitmap: Width = map.PixelHeight; Height= map.PixelWidth; Stream stream = map.PixelBuffer.AsStream(); byte[] pixels = new byte[stream.Length]; stream.Seek(0, 0); stream.Read(pixels, 0, pixels.Length); [...] //Write PixelBuffer back Stream stream = map.PixelBuffer.AsStream(); stream.Seek(0, 0); stream.Write(pixels, 0, pixels.Length); map.Invalidate(); [...] //Create an empty WriteableBitmap pixels = new byte[ Width * Height << 2]; WriteableBitmap map = new WriteableBitmap(Width,Height); Stream stream = map.PixelBuffer.AsStream(); stream.Seek(0, 0); stream.Write(pixels, 0, pixels.Length); map.Invalidate(); [...] //set pixel public void setPixel(int x, int y, uint rgba) { int stride = Width; int index = (y * stride + x) << 2; pixels[index] = (byte)((rgba >> 24) & 0xff); pixels[index+1] = (byte)((rgba >> 16) & 0xff); pixels[index+2] = (byte)((rgba >> 8) & 0xff); pixels[index+3] = (byte)(rgba & 0xff); }
All Replies
-
Monday, April 09, 2012 2:06 PM
It looks indeed like the problem is somewhere in Stream.write() - I a have switched to using BitmapDecoder to read the image file and the stride problem has gone away:
ImageProperties props = await file.Properties.GetImagePropertiesAsync(); BitmapDecoder decoder = await BitmapDecoder.CreateAsync(await file.OpenAsync(FileAccessMode.Read)); BitmapTransform transform = new BitmapTransform(); transform.Bounds = new BitmapBounds() { Width = props.Width, Height = props.Height }; PixelDataProvider pixelData = await decoder.GetPixelDataAsync(BitmapPixelFormat.Rgba8, decoder.BitmapAlphaMode, new BitmapTransform(), ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage); byte[] pixels = flipRGBA( pixelData.DetachPixelData()); WriteableBitmap map = new WriteableBitmap(props.Width, props.Height); Stream stream = map.PixelBuffer.AsStream(); stream.Seek(0, 0); stream.Write(pixels, 0, pixels.Length); map.Invalidate();
- Proposed As Answer by James Dailey - MSFTMicrosoft Employee, Moderator Wednesday, April 11, 2012 11:41 PM
-
Wednesday, April 11, 2012 11:42 PMModerator
Hello Quasimondo,
Do you feel that your stride question is answerd by using the BitmapDecoder? This certainly sounds like the way to go.
Thanks,
James
Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/
-
Thursday, April 12, 2012 8:53 AMWell, BitmapDecoder surely solves it for me, but just out of curiosity I still would like to know what happens under the hood with the Stream method and why it causes this effect.


