Graphics g;
using (var bmp = new Bitmap(_frame, _height, PixelFormat.Format24bppRgb))
{
var data = bmp.LockBits(new Rectangle(0, 0, _frame, _height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
var bmpWidth = data.Stride;
var bytes = bmpWidth * _height;
var rgb = new byte[bytes];
var ptr = data.Scan0;
Marshal.Copy(ptr, rgb, 0, bytes);
for (var i = 0; i < _frame; i++)
{
var i3 = (i << 1) + i;
for (var j = 0; j < _height; j++)
{
var ij = j * bmpWidth + i3;
var val = (byte)(_values[i, j]);
rgb[ij] = val;
rgb[ij + 1] = val;
rgb[ij + 2] = val;
}
}
Marshal.Copy(rgb, 0, ptr, bytes);
bmp.UnlockBits(data);
g = _box.CreateGraphics();
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(bmp, 0, 0, _box.Width, _box.Height);
}
g.Dispose();
I use this code to convert an array of RGB values (grayscale) in the PictureBox, but it's slow. Please tell me my mistakes. At the moment, an array of 441 000 items handled for 35 ms. I need to handle an array of 4 million for the same time.
Try this using unsafe code:
Runs very fast for me
In addition to Guffa's excellent advice, I would suggest that you profile your code to see where it's taking the time. Be sure that when you're timing this, you are running in release mode without the debugger attached.
I wouldn't be surprised if the call to
DrawImage
is taking up most of the time. You're scaling the image there, which can be pretty expensive. How large is the box that you're drawing the image to?Finally, although this won't affect performance, you should change your code to read:
And get rid of the first and last lines in your example.
You can skip the first
Array.Copy
where you copy the data from the image to the array, as you will be overwriting all the data in the array anyway.That will shave off something like 25% of time, but if you want it faster you will have to use an unsafe code block so that you can use pointers. That way you can get around the range checking when you access arrays, and you can write the data directly into the image data instead of copying it.
My understanding is that multidimentional (square) arrays are pretty slow in .Net. You might try changing your _values array to be a single dimension array instead. Here is one reference, there are many more if you search: http://odetocode.com/articles/253.aspx
Array perf example.
I totally agree with Guffa's answer. Using an unsafe code block will speed up things. To further improve performance, you could execute your for loop in parallel by using the
Parallel
class in the .Net framework. For large bitmaps this improves performance. Here is a small code sample:To keep the example simple I've set the pixel values to a constant value. Note, to compile the example above you have to allow unsafe code.
Hope, this helps.