
Signature
--
Bob Powell [MVP]
Visual C#, System.Drawing
Ramuseco Limited .NET consulting
http://www.ramuseco.com
Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm
Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm
All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
> Hi John,
> What performance issues are you having with LockBits? If you're
> programming C# then you should surely be using unsafe code and not the
> Marshal class for access.
Did you look at my code? I'm not sure what you mean by unsafe and
marshaling? I used unsafe to access the lockbits... its all in the code I
pasted...
crap... lol, I guess I didn't paste any code ;/
Ok, here it is... Its kinda messy but shows what I'm doing when using
lockbits(I pretty much copied and pasted from some other site that said to
use this method.
When I run this under VS I get about 1fps. When I run it outside of VS I get
about 10-20fps or so. (it might actually be fast but its slightly jerky)
Thanks,
Jon
bmd = bitmap.LockBits(R, System.Drawing.Imaging.ImageLockMode.ReadOnly,
bitmap.PixelFormat);
unsafe
{
for (int y = 0; y < bmd.Height; y++)
{
byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
for (int x = 0; x < bmd.Width; x++)
{
c = (int)(t) % 255;
row[x * PixelSize + 2] = (byte)(255*(Math.Pow((c/255F),0.8)));
row[x * PixelSize + 1] = (byte)(255*(Math.Pow((c/255F),2)));
row[x * PixelSize + 0] = (byte)(255*(Math.Pow((c/255F),3)));
}
}
} // unsafe
bitmap.UnlockBits(bmd);
BitmapGraphics2.DrawImage(bitmap, 0, 0);
Ben Voigt [C++ MVP] - 11 Sep 2007 01:41 GMT
>> Hi John,
>> What performance issues are you having with LockBits? If you're
[quoted text clipped - 20 lines]
> bmd = bitmap.LockBits(R, System.Drawing.Imaging.ImageLockMode.ReadOnly,
> bitmap.PixelFormat);
ReadOnly doesn't look right for this.
> unsafe
>
[quoted text clipped - 27 lines]
>
> BitmapGraphics2.DrawImage(bitmap, 0, 0);
Which part is the slowdown (use Diagnostics.Stopwatch)? The LockBits,
filling in the array, UnlockBits, or DrawImage?
I doubt the computations are the bottleneck, but you can surely remove some
redundant code there, use repeated addition to find row instead of
multiplying by y, precompute x*PixelSize, and (c / 255). Also multiplying
will be much faster than Math.Pow for the integral cases.
If I'm right and the for loops are fast enough, then you can surely get a
very good frame rate (i.e. hit monitor's refresh rate with plenty of cycles
to spare) using OpenGL with glDrawPixels. A little more work for you, but
you'll get direct transfers to video memory and thence to the screen. If
you move up to a texture with glTexImage2D, a lot of effects become
essentially free at that point as well (transparency for watermarking or
fading in and out, rotation, stretching, etc).
Jon Slaughter - 11 Sep 2007 06:16 GMT
>>> Hi John,
>>> What performance issues are you having with LockBits? If you're
[quoted text clipped - 70 lines]
> become essentially free at that point as well (transparency for
> watermarking or fading in and out, rotation, stretching, etc).
Yes, I should be able to get it a good frame rate. I just need to work at
the pixel level because I am trying to do a physics simulation. The display
is only to display the result of the simulation periodically. I have some
other simulations that I've done but I didn't use lock bits and they seem
pretty fast. This is first time I'm using lock bits but potentially code is
slow when I'm actually doing the simulation(but shouldn't be that slow).
What I did notice is that when I run it under VS its about 20 times slower
even if in active mode. So the debugger is making it very slow and I
probably got confused when I was running it and with the simulation.
Essentially I'm calculating two gaussians and maybe the math library is
pretty slow. I guess I'll need to precalculate the guassians and see how
that works. I'll try to profile it sometime but distracted writing a vector
library ATM.
Thanks,
Jon
Ben Voigt [C++ MVP] - 12 Sep 2007 02:15 GMT
>>>> Hi John,
>>>> What performance issues are you having with LockBits? If you're
[quoted text clipped - 86 lines]
> that works. I'll try to profile it sometime but distracted writing a
> vector library ATM.
Ah, yes, with only 256 values a lookup table will be several orders of
magnitude faster than calling Pow inside the loop. I hadn't even considered
that. I really meant for you to first measure timing and find out which
part was the bottleneck.
> Thanks,
> Jon
Jon Slaughter - 12 Sep 2007 05:05 GMT
>>>>> Hi John,
>>>>> What performance issues are you having with LockBits? If you're
[quoted text clipped - 91 lines]
> considered that. I really meant for you to first measure timing and find
> out which part was the bottleneck.
But I commented out the calculation and it was just as slow. I think it has
to do when in debugging mode. Anyways, I started a new projected and used
lock bits and its much faster... I guess I can get around 40 frames per
second when just changing the colors in a simple way.
Strangely though I rewrote Exp to use lookups and its no faster than
Math.Exp... so I gotta see what I can do about that ;/
Thanks,
Jon
Ben Voigt [C++ MVP] - 12 Sep 2007 15:39 GMT
>>>>>> Hi John,
>>>>>> What performance issues are you having with LockBits? If you're
[quoted text clipped - 100 lines]
> Strangely though I rewrote Exp to use lookups and its no faster than
> Math.Exp... so I gotta see what I can do about that ;/
You built a lookup array for c => (byte)(255*(Math.Pow((c/255F),0.8))),
right?
That will be much faster than a Dictionary<float, float> for Math.Pow
itself. Also, the overhead of lazy initialization is going to be
considerable, just precompute the whole table.
Actually, you can use an int* instead of byte* in your unsafe loop, and
return the whole R-G-B composite from the lookup table.
> Thanks,
> Jon
Doug Semler - 11 Sep 2007 05:49 GMT
>> Hi John,
>
> bmd = bitmap.LockBits(R, System.Drawing.Imaging.ImageLockMode.ReadOnly,
> bitmap.PixelFormat);
ReadOnly works for you here? I've always gotten "attempt to write to
protected memory" exceptions whenever I tried to write to memory I've
obtained via a readonly lockbits <g>
What is the original bitmap's depth/pixel format? If I rember correctly, i
have had performance problems in the past with LockBits when using palette
(8bpp grayscale) bitmaps created from jpegs.

Signature
Doug Semler, MCPD
a.a. #705, BAAWA. EAC Guardian of the Horn of the IPU (pbuhh).
The answer is 42; DNRC o-
Gur Hfrarg unf orpbzr fb shyy bs penc gurfr qnlf, abbar rira
erpbtavmrf fvzcyr guvatf yvxr ebg13 nalzber. Fnq, vfa'g vg?
Jon Slaughter - 11 Sep 2007 06:13 GMT
>>> Hi John,
>>
[quoted text clipped - 4 lines]
> protected memory" exceptions whenever I tried to write to memory I've
> obtained via a readonly lockbits <g>
I write ReadWrite and others and all the same result. The page I got this
code from had ReadOnly so I kepted it. Since I don't really know what it
does I kepted it like that. (even though one would expect that it would
prevent writing to the bits).
> What is the original bitmap's depth/pixel format? If I rember correctly,
> i have had performance problems in the past with LockBits when using
> palette (8bpp grayscale) bitmaps created from jpegs.
32bit. ARGB. I guess atleast. I'm just creating a standard bitmap which I
suppose uses the display device parameters. Didn't really bother with
checking since I figure if it was something strange then it wouldn't look
right. (if it was 16 bits then and I treated it was 32bit then I wouldn't
get the correct picture).