[WinRT] - SetPixel very very slow and help for algorithm

Jun 19, 2012 at 2:45 PM
Edited Jun 19, 2012 at 3:01 PM

Hi,

I am trying to migrate some code from GDI/DibSection to WriteableBitmapEx on WinRT.
I am calling a native library that is supposed to fill a buffer with BGRA data and I am trying to display it from my Metro application.

Here is how I am doing it :

private void PaintImage(WriteableBitmap bitmap)
{
            lock (locker)
            {

                var stream = bitmap.PixelBuffer.AsStream();

                int width =  bitmap.PixelWidth;
                int height = bitmap.PixelHeight;
                int stride = (width + 3) & (~3);
                int sizeImage = width*height*4;

                // Fill our buffer with data
                IntPtr buffer = rmsdk_getBuffer();
                byte[] imageData = new byte[sizeImage];
                Marshal.Copy(buffer, imageData, 0, sizeImage);
               
                stream.Write(imageData, 0, imageData.Length);
                bitmap.Invalidate();
	    }
}

 

 However the resulting image seems to be deformed with some kind of rotation and stretch, so I wanted to test the SetPixel method and to test it simply I wrote this  :

For information my bitmap is 362x468

 

Color c = Colors.Red;
for (int x = 0; x < bitmap.PixelWidth; x++)
{
    for (int y = 0; y < bitmap.PixelHeight; y++)
    {
        bitmap.SetPixel(x, y, c);
    }
}

 However I have started the test 10 minute ago and the x is only at 27 the last
time I had a look (1s ago) so it's very very very slow.

Do you have any idea why ?

So now I would be tempted to use WriteByte, but I Am not sure how to get the
right index inside my imageData array :

for (int x = 0; x < bitmap.PixelWidth; x++)
{
    for (int y = 0; y < bitmap.PixelHeight; y++)
    {
        
        stream.WriteByte(imageData[ ???? ]);
        stream.WriteByte(imageData[ ???? ]);
        stream.WriteByte(imageData[ ???? ]);
        stream.WriteByte(imageData[ ???? ]);
    }
}
Any help would be appreciated
Coordinator
Jun 19, 2012 at 5:50 PM

Don't use the SetPixel method for mass pixel manipulation. Implement it on your own. See the BitmapConext.CopyPixels method on how to access the pixels in the right order, then look at the SetPixel method.

If you want to use the SetPixel or any other WriteableBitmapEx method, then do it that way inside a BitmapContext scope to avoid an unnecessary overhead:

using (bitmap.GetBitmapContext())
{
	Color c = Colors.Red;
	for (int x = 0; x < bitmap.PixelWidth; x++)
	{
		for (int y = 0; y < bitmap.PixelHeight; y++)
		{
			bitmap.SetPixel(x, y, c);
		}
	}
}

 

- René Schulte