Search code examples
c#wpfwriteablebitmap

WriteableBitmap set pixels


I am using WPF and i would like to manipulate some pixels of my image. I am using WritableBitmap because i can use it indirect from source. When i try to set some pixels RGB values (in order), the result is not that i expected. I use this extension method to read source:

        public static PixelColor[,] CopyPixels(this BitmapSource source,out int stride)
        {
            if (source.Format != PixelFormats.Bgra32)
                source = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0);
                PixelColor[,] pixels = new PixelColor[source.PixelWidth, source.PixelHeight];
                stride = source.PixelWidth * ((source.Format.BitsPerPixel + 7) / 8);
                GCHandle pinnedPixels = GCHandle.Alloc(pixels, GCHandleType.Pinned);
                source.CopyPixels(
                  new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight),
                  pinnedPixels.AddrOfPinnedObject(),
                  pixels.GetLength(0) * pixels.GetLength(1) * 4, stride);

            pinnedPixels.Free();
            return pixels;
        }

The output struct is

[StructLayout(LayoutKind.Sequential)]
public struct PixelColor
{
    public byte Blue;
    public byte Green;
    public byte Red;
    public byte Alpha;
}

this is the simple example code to modify pixels (between 200x200 and 300x300) to black:

        int stride = 0;
        PixelColor[,] PixelData = wBitmap.CopyPixels(out stride);

        for (int i = 0; i < PixelData.GetLength(0); i++)
        {
            for (int j = 0; j < PixelData.GetLength(1); j++)
            {

                if ((200 < i && 300 > i) && (200 < j && 300 > j))
                {
                    PixelData[i, j].Blue = 0;
                    PixelData[i, j].Red = 0;
                    PixelData[i, j].Green = 0;

                }

            }
        }

        wBitmap.WritePixels(new Int32Rect(0, 0, wBitmap.PixelWidth, wBitmap.PixelHeight), PixelData, stride,0);

The surprising result is enter image description here

This is an image with 500x500 parameters. I expected that the result will be an black filled square in the middle of the image instead of black vertical lines. What is the problem with my example code? (The colorful dots behind the lines are part of the original image.)


Solution

  • Just change the order of the dimensions in the 2-dimensional array declaration in your CopyPixels methods:

    var pixels = new PixelColor[source.PixelHeight, source.PixelWidth];