Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Wanet Telecoms Ltd on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

GDI+ Performance help 1

Status
Not open for further replies.

Frush

Programmer
Jun 27, 2002
75
CA
Hi, I have small/big problem with on of my application.

I made a "mini-paint" for work and I have some performance problem. Depending on what system I test it:

A) works perfectly
B) its choppy

I think the main reason why it look choppy is because of graphics.DrawImage().

The disturbing part is that I tryed my application on 2 system with the exact same config (cpu/ram/window xp sp2) on one of the system it works perfectly the other one is choppy.

Is there some special update or something like that that I need to install? Been googling for updates but didnt find anything that seem related to my problem, any help would be appreciate.

Ps: excuse my poor english.
 
Maybe the display settings on the two test machines are different? Anyways, are you drawing your GDI objects directly onto the form's graphics objects, or are you using an in memory bitmap to draw all at once?
 
Nah we tryed different resolution drivers and so on. The weird part is that I tryed it on a computer a bit "weaker" than my first test and it work perfectly on the "weaker" one.

I'm using a memory bitmap but anyway I wont change my code. 2 computers with the exact same setting (they are Dell's) should give about the same result right? I need to find whats missing.
 
Whenever I have worked with GDI+ in the past, if it has been developed correctly, I haven't seen any choppiness. I do recall one instance where I had different drawing behavior (although not related to performance/choppiness) when using .Net 1.0 vs. 1.1. Are the two PC's executing your application using the same framework version and framework service pack?
 
Well this is what I will find out a bit later today when my test subject go get lunch.

I can explain you a bit what I'm doing with my application maybe you can give me tips.

The hardess part was to simulate a "growing" line when you want to draw a straight line like in MsPaint.

To do so on every mouse move event I repaint the rectangle where the line was and draw a new line. To do so I use DrawImage(backupImage,rectangle, rectangle. pixel) I know this is slow I tryed using bitblt but havent been able to make it work for what I want (I was always getting a black rectangle).

I really tryed to optimise my drawing by repainting only the modified region and it seem to work alright.. depending on what computer I'm using it
 
If I add lines to a GraphicsPath on MouseMove and draw the entire path to an in-Memory bitmap during MouseMove, and redraw the entire bitmap in OnPaint, I don't get any choppiness or flickering, as long as I override OnPaintBackground.
 
I'm using a picturebox right now for my pictures and I dont dont paint in the "OnPaint" event... wish I could give you my code so you take a look, ill past my main painting class maybe it will help explaining what I'm doing.

(btw I have 0 problem with "hand writting" this works perfectly on any computer)

This is the function I use on mouseMove when the user select a "straight line"

'----------------------------------------------------------
Public Function RealLine(ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer) As Rectangle
Dim rect As New Rectangle


Static Dim oldX2 As Integer
Static Dim oldY2 As Integer


If tmpbitmap Is Nothing Then
tmpbitmap = New Bitmap(m_bitmap.Width, m_bitmap.Height)
graphics = graphics.FromImage(tmpbitmap)

graphics.DrawImageUnscaled(m_bitmap, 0, 0)

graphics = graphics.FromImage(m_bitmap)
graphics.SmoothingMode = SmoothingMode.AntiAlias

Else



If X1 < oldX2 AndAlso Y1 < oldY2 Then
rect.X = X1 - 10
rect.Y = Y1 - 10
rect.Width = oldX2 - X1 + 20
rect.Height = oldY2 - Y1 + 20


graphics.DrawImage(tmpbitmap, rect, rect, GraphicsUnit.Pixel)

' graphics.DrawImage(tmpbitmap, rect(X1, Y1, oldX2, oldY2), New Rectangle(X1, Y1, oldX2, oldY2), GraphicsUnit.Pixel)
'graphics.DrawLine(New Pen(Color.Black, 5), X1, Y1, X2, Y2)
ElseIf oldX2 < X1 AndAlso oldY2 < Y1 Then
rect.X = oldX2 - 10
rect.Y = oldY2 - 10
rect.Width = X1 - oldX2 + 20
rect.Height = Y1 - oldY2 + 20

graphics.DrawImage(tmpbitmap, rect, rect, GraphicsUnit.Pixel)
'graphics.DrawLine(New Pen(Color.Black, 5), X1, Y1, X2, Y2)
ElseIf X1 < oldX2 AndAlso oldY2 < Y1 Then
rect.X = X1 - 10
rect.Y = oldY2 - 10
rect.Width = oldX2 - X1 + 20
rect.Height = Y1 - oldY2 + 20

graphics.DrawImage(tmpbitmap, rect, rect, GraphicsUnit.Pixel)

ElseIf oldX2 < X1 AndAlso Y1 < oldY2 Then

rect.X = oldX2 - 10
rect.Y = Y1 - 10
rect.Width = X1 - oldX2 + 20
rect.Height = oldY2 - Y1 + 20

graphics.DrawImage(tmpbitmap, rect, rect, GraphicsUnit.Pixel)

End If

graphics.DrawLine(New Pen(Color.Black, 1), X1, Y1, X2, Y2)

oldX2 = X2
oldY2 = Y2

Return rect
End If



End Function

the function return the modified rectangle and its only that part of the picture that I invalidate with PictureBox1.Invalide(Rect)
 
I've never implemented an app where I've redrawn just the changed rectangles, so it's difficult for me to say. I've always redrawn the entire image to the form or the control. That being said, when I've redrawn the entire image, both the free-hand method and the straight lines work fine without any choppiness.
 
Well "free-hand" dont require any special effect this is why I have no problem. If I was drawing straight lines with no "special effect" I would have no problem eighter. The problem comes from the fact that I need to "reset" the image on every mouseMouve to simulate a growing line ( a la paint)

I'm sorry its a bit hard to explain and I'm not very good at explaining + english is not my "first language".
 
I'm still not sure why the growing line effect would change the performance. I had used another GraphicsPath object that I reset when the mouse was down and moved and when the mouse button was released to hold the growing line. It worked fine on my screen.
 
I havent use GraphicsPath so far I'm using a specific algo for my "free drawing" (fast_line by Hong something). I'll take a look on how GraphicPath, dont you have to "reset" the modified part of the picture (or the whole picture) to have a "growing" effect?
 
My temporary GraphicsPath in this case contains one Line. Each time the mouse is moved while the mouse button is down, I Reset the GraphicsPath object which eliminates the Line. Then I redraw the line from the same starting point to the new coordinates where the mouse is located. Each time this happens, the bitmap is cleared, the GraphicsPath is drawn on the bitmap, and the bitmap is drawn on the screen. So, in effect, the line really isn't growing or being appending to. I am creating a new line each time when the mouse is moved. This makes it looks like the line is growing.
 
Pretty much the samething I'm doing except I use drawline instead of graphicspath (makes me wonder why you use that). I made more test this afternoon and so far 50% of the computer I test works fine.. more investigating will be require. thanks for your help
 
Just to let you know that I fix my problem with this line

tmpbitmap = New Bitmap(m_bitmap.Width, m_bitmap.Height, PixelFormat.Format32bppPArgb)

by setting the pixelformat to Format32bppPargb I improve performance a lot and its now working on every station.

Thanks again for your help
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top