here is the code is there any way to make it faster cause its slowerden single
public Bitmap pSetInvert(Bitmap _currentBitmap)
{
Bitmap temp = (Bitmap)_currentBitmap;
Bitmap bmap = (Bitmap)temp.Clone();
Color c;
Parallel.For(0, bmap.Width, i =>
{
lock (bmap)
{
for (int j = 0; j < bmap.Height; j++)
{
c = bmap.GetPixel(i, j);
bmap.SetPixel(i, j, Color.FromArgb(255 - c.R, 255 - c.G, 255 - c.B));
}
}
});
return (Bitmap)bmap.Clone();
}
By using
lock
you are making parallel part of your code to work serially, exactly like a single thread application with synchronization overhead so it actually would be slower.here is a helper class that access bitmap data directly and you can manipulate image in concurrently.
FastImage Helper Class:
and here is your code using
FastImage
class:The
lock
in theParallel.For
is going to cause the code to run slower than with a single-threaded loop. The lock only allows one thread at a time to do useful work, with the added cost of acquiring the lock.Additionally, GetPixel and SetPixel are extremely slow. They are also not guaranteed to be thread-safe, which is probably why you are getting the InvalidOperationException
http://msdn.microsoft.com/en-us/library/System.Drawing.Bitmap(v=vs.110).aspx
Have a look instead at WriteableBitmap. Though the class was introduced with WPF, you can use it from a variety of environments. I recently used it in a console application. WriteableBitmap can be converted to a standard bitmap if needed, or written to a ".bmp" file.
Alternatively, you can use unsafe code to directly access the Bitmap buffer.
If you need to, you can use multiple threads for either WriteableBitmap or unsafe access to the Bitmap buffer since you are directly reading/writing memory.
Here are two versions of your filter routine you can play with. They take the image of one
PictureBox
and after running through the filter assign it to a secondPictureBox
.LockBits
and can do 10.000 (!) loops for a ca 400x400 image in 40 seconds on my machine.Parallel.For
in addition to theLockBits
and does the same job in 35 seconds here.Of course these timings are strongly influenced by overhead (and maybe by dumb bugs I made.) But really, using
Lockbits
is key to speed here as there is so little to 'compute' the parallelization management itself eats up most of the cores' time..Note that the 2nd filter routine needs to work on a second Bitmap for general purpose filter algorithms. This simple inversion filter doesn't really need it, but once you write things that access neighbouring pixels like eg.g a blur filter you do..
Also note the order of the channel bytes!