Why is this code so slow??!?

mickn66

Well-known member
Joined
Nov 2, 2002
Messages
53
I have a program that is supposed to take a 300 by 200 pixel image and examine it one 5 by 5 block at a time. However, it is extremely slow. The following is the code that does the looping (spotsize is 5):

Dim x, y As Integer
For y = 0 To pct1.Height - spotsize Step spotsize
For x = 0 To pct1.Width - spotsize Step spotsize
spot.X = x
spot.Y = y
DrawSpot()
Next x
Next y
MsgBox("done")

"DrawSpot" is the function that analyzes each spot and thats where the trouble is, because without it, the above code takes about 1 second to run. Drawspot does 3 things. It draws a red rectangle around the spot in pct1, it draws the spot onto pct2, which is 50x50 and set to strectchimage mode, thereby showing a close up of spot, and it analyzes the brightness of spot (not in this order).

Here is the code for DrawSpot():

Private Sub DrawSpot()

Dim biggy As New Rectangle(0, 0, 50, 50) rectangle for pct2
Dim g2 As Graphics = pct2.CreateGraphics to draw on pct2
Dim bitty As New Bitmap(pct1.Image) source image of pct1
Dim g As Graphics = Graphics.FromHwnd(pct1.Handle) to draw on pct1


g2.DrawImage(bitty, biggy, spot, GraphicsUnit.Pixel)

calculate brightness of spot before drawing rectangle
Dim x, y As Integer
Dim aColor As Color
Dim total As Double = 0
Dim counter As Integer = 0
For x = spot.Left To spot.Right
For y = spot.Top To spot.Bottom
aColor = bitty.GetPixel(x, y)
total = total + aColor.GetBrightness
counter = counter + 1
Next y
Next x
lblBrightness.Text = CStr(total / counter)

draw the rectangle on Spot on pct1
Dim myPen As New Pen(Color:=Color.Red, Width:=2)
g.DrawRectangle(myPen, spot)
End Sub

I dont understand why it slows it down as much as it does. Have I done something horribly stupid? Is there a faster way? Thanks!

Mick
 
Either use global variables for the variables that never change
OR
Dont use DrawSpot and put all the code within the loop, declaring the variables that never change before the loop.

You are creating new variables each loop and that will really slow the program down. Especially when it is a Bitmap:

Dim biggy As New Rectangle(0, 0, 50, 50) rectangle for pct2
Dim g2 As Graphics = pct2.CreateGraphics to draw on pct2
Dim bitty As New Bitmap(pct1.Image) source image of pct1
Dim g As Graphics = Graphics.FromHwnd(pct1.Handle) to draw on pct1
 
Thank you. I was just beginning to suspect it was all the dim statements, since Ive commented out almost everything else and its still so slow! Im going to try global variables first.
 
If you want maximum speed you can get drawing then you would need to use the paint event of the object you want to draw on and use the Graphics object thats passed into the event in PaintEventArgs, and then set the style for it: Double Buffering, All Painting in WM Paint, and user Paint.
 
Im not sure I understand. What do you mean I can "get drawing"? And "Double Buffering, All Painting in WM Paint, and user Paint" - This sounds like something I should know by now :) But I dont.

I sure would like maximum speed though! Any more information you can give me would be appreciated. Thanks
 
He is talking about putting your code in Form.OnPaint method and Double Buffing the Form so that there is no flicker.

Put the equivalent of this C# code in your Forms constructor:
C#:
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);

To call OnPaint call, Invalidate()
In Invalidate you can draw only the pixel that will be changed instead of drawing the whole form over again by sending a Rectangle to Invalidate of the area that will be changed. It will be much much faster that way.
 

Similar threads

V
Replies
0
Views
150
Vergassivellaunus
V
V
Replies
0
Views
154
Vergassivellaunus
V
Back
Top