I wrote function:
public static byte[, ,] Bitmap2Byte(Bitmap image)
{
int h = image.Height;
int w = image.Width;
byte[, ,] result= new byte[w, h, 3];
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
Color c= image.GetPixel(i, j);
result[i, j, 0] = c.R;
result[i, j, 1] = c.G;
result[i, j, 2] = c.B;
}
}
return result;
}
But it takes almost 6 seconds to convert 1800x1800 image. Can I do this faster?
EDIT:
OK, I found this: http://msdn.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.aspx
There is nice example. Only question I have is about Marshal.Copy
. Can I make it copy data directly into byte[,,]
?
EDIT 2:
OK, sometimes I got strange values of pixels and they do not seem to follow r0 g0 b0 r1 g1 b1 rule. Why? Never mind. Figured it out.
EDIT 3: Made it. 0,13s vs 5,35s :)
You can speed this up considerably by using a BitmapData
object which is returned from Bitmap.LockBits
. Google "C# Bitmap LockBits" for a bunch of examples.
GetPixel
is painfully, painfully slow, making it (ironically) completely unsuitable for the manipulation of individual pixels.
I've been wondering this for a while.
In .NET 4.0 Microsoft introduced the Parallel library. Basically what this does is there is a Parallel.For method that will automatically spawn off numerous threads to help with the work. For instance if you originally had a For(int i =0;i<3;i++){ code...}, A parallel.For loop would probably create 3 threads and each thread would have a different value for i running through the inner code. So the best thing i can suggest is a Parallel.For loop with a
Color c
lock(obraz)
{
c = obraz.GetPixel(..)
}
...
when getting the pixel.
If you need any more explanation on parallelism I can't really assist you before you take some time to study it as it is a huge area of study.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With