Problem with Form.DrawImage !!

mikkevin

Member
Joined
Nov 5, 2009
Messages
10
Programming Experience
10+
I've got the following loop, which draws the image bmOffScreenImage in triangular transition from the centre of the screen. The first DrawImage starts from the centre and works towards the sides and to the top and it is working right but, the second doesn't for some reason I can't seem to figure out. The second draws same kind of triangle but works it way downwards from the centre of the screen.

Here's an ascii representation of what I'm trying to do.

VB.NET:
      - - - - - - - - -
      | \              /|
      |   \          /  |
      |     \      /    |
      |      /     \    |
      |    /         \  |
      | /              \|
      - - - - - - - - -

I'm trying to draw the image in four triangles transitioning outwards from the centre. Here's the code that draws the upper and lower triangles. The upper triangle draws just fine but, the lower one doesn't draw and seems to be missing few horizontal lines every now and then.

VB.NET:
For i = 0 To Me.Width / 2
                    If i <= Me.Height / 2 Then
                        m_Graphics.DrawImage(bmOffScreenImage, CType(Me.Width / 2, Integer) - i, CType(Me.Height / 2, Integer) - i, New Rectangle(CType(Me.Width / 2, Integer) - i, CType(Me.Height / 2, Integer) - i, 2 * i, 1), GraphicsUnit.Pixel)
                        m_Graphics.DrawImage(bmOffScreenImage, CType(Me.Width / 2, Integer) - i, CType(Me.Height / 2, Integer) + i - 1, New Rectangle(CType(Me.Width / 2, Integer) - i, CType(Me.Height / 2, Integer) + i - 1, 2 * i, 1), GraphicsUnit.Pixel)
                        Debug.Print(i & " " & CType(Me.Width / 2, Integer) - i & " " & CType(Me.Height / 2, Integer) + i)
                    End If
Next i

The debug.print prints the all the three parameters and I don't see it skipping any coordinate values in between.

I hope the above is clear enough, otherwise I can blame it on the beer in my veins and post a screenshot to make it clearer !

Thanks for any help.

EDIT: Can't get that damned ASCII art in right format ! Anyways, here's a screenshot.
 

Attachments

  • CropperCapture[1].jpg
    CropperCapture[1].jpg
    82 KB · Views: 56
Last edited:
I haven't given your code logic much thought, but may I suggest you refactor it:
VB.NET:
Dim w As Integer = CInt(Me.Width / 2)
Dim h As Integer = CInt(Me.Height / 2)
For i As Integer = 0 To w
    If i <= h Then
        m_Graphics.DrawImage(bmOffScreenImage, w - i, h - i, New Rectangle(w - i, h - i, 2 * i, 1), GraphicsUnit.Pixel)
        m_Graphics.DrawImage(bmOffScreenImage, w - i, h + i - 1, New Rectangle(w - i, h + i - 1, 2 * i, 1), GraphicsUnit.Pixel)
        Debug.Print(i & " " & w - i & " " & h + i)
Though at first sight it seems ok, so does the output here, but "m_Graphics" looks suspicious, what Graphics object is this and in what context is it used?
 
Thanks very much JohnH.

I tried your code and it still leads to the same behaviour. The only difference lies in our code is in the type conversion - you're using CInt, I'm using CType i.e. ignoring the refactoring of the code to make use of the variables w & h.

I have coded several other transitions using the m_Graphics object and never had any problems with it except the one we are talking about.

Here's the declarations relevant to m_Graphics:
Private bmOffScreenImage As Bitmap
Private bmImageFile As Bitmap
Private gpOffScreenGraphics As Graphics

Me.m_Graphics = Me.CreateGraphics()

bmImageFile = New Bitmap(strNextImage)

bmOffScreenImage = New Bitmap(Me.Width, Me.Height, m_Graphics)
gpOffScreenGraphics = Graphics.FromImage(bmOffScreenImage)

bmImageFile is the original image which is used by gpOffScreenGrahics. gpOffScreenGraphics is the graphics object which, which in turn prepares the image bmOffScreenImage in the background (involves some stretching, tiling etc.) . Later bmOffScreenImage is used by the m_Graphics object to paint it on the form itself in transitions.

So, is there something I'm missing or doing wrong ?

Though at first sight it seems ok, so does the output here, but "m_Graphics" looks suspicious, what Graphics object is this and in what context is it used?

Thats making me feel that I'm doing something wrong, but not sure what !!?

Thanks again.

PS: I noticed the ASCII art is envlosed in quotes and looks nice. I'm presuming that it was you. Thanks very much and apologies for the sillyness !
 
I tried your code and it still leads to the same behaviour.
It wasn't my code, it was exactly the same as your code, I only changed repetetive code using two variables.
Me.CreateGraphics()
CreateGraphics is not supposed to be used to draw with. Use the Paint event where you use e.Graphics to draw with. What you saw was most likely due to this causing refresh problems.
PS: I noticed the ASCII art is envlosed in quotes and looks nice. I'm presuming that it was you.
Yeah, the code block has the same effect as a html Pre tag and can be used to present spaced layout.
 
Thanks for the reply, John.

CreateGraphics is not supposed to be used to draw with. Use the Paint event where you use e.Graphics to draw with. What you saw was most likely due to this causing refresh problems.

That reminds me of the problem I'd with my previous application I was developing. Using CreateGraphics, I couldn't even get it to paint the image ! I had to use the form's Paint method to get it done.

Btw, you are saying CreateGraphics shouldn't be used to draw with. Could you please clarify a bit ? According to msdn article How to: Create Graphics Objects for Drawing you can use CreateGraphics to draw anything on any control except web controls. It apparently is woriking for me except the problem I faced and started this thread !

With this current project, I had to use CreateGraphics as, I'm a bit lost when it comes to form's Paint method. I have several of these transitions which use different overloads of Drawimage and I can't figure out how I can include them in Paint method. Looks like it is gonna take a long time to learn this .NET thing !!

Any thoughts ?

Yeah, the code block has the same effect as a html Pre tag and can be used to present spaced layout.

Thanks for that info ! :eek:

Thanks again.
 
See the remarks in help topic for this method Control.CreateGraphics Method (System.Windows.Forms) and this article: When to use CreateGraphics.

While you can use CreateGraphics in Paint event and use it to paint with why would you when a valid Graphics object is already provided? I have no idea why MS has added CreateGraphics for examples on how to paint on controls, that makes no sense to me. If you still want to you can also use CreateGraphics from any event and force a temporary Paint-over, but realize that anytime may the control repaint and what you painted there previously will be gone. The only way for you to ensure that what you paint remains (until next Paint event) is to respond to the Paint event.
With this current project, I had to use CreateGraphics as, I'm a bit lost when it comes to form's Paint method. I have several of these transitions which use different overloads of Drawimage and I can't figure out how I can include them in Paint method. Looks like it is gonna take a long time to learn this .NET thing !!
If you can use one Graphics object you can also use another. When you say Paint method you should say and think Paint event. The Paint method is the handler for the Paint event, when system or internal code want the window to repaint itself a message is sent, control repaints and raise Paint event, when you handle this event you do that with the Paint method and here you can do custom painting. Of course you can have any number of methods that you call from Paint event handler, just pass the Graphics object you're supposed to paint with to them. If you at any point want to force the control to repaint you either call Refresh method or the Invalidate/Update methods, this causes the Paint event to be raised.
 
Thanks again JohnH.

I have been browsing msdn and came across pages that were relevant to the graphics object including the one that you just mentioned (Control.CreateGraphics Method (System.Windows.Forms)).

Now, I have changed my code as follows:

VB.NET:
Private bmOffScreenImage As Bitmap
Private bmImageFile As Bitmap
Private gpOffScreenGraphics As Graphics

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        
        strNextImage=GetNextImage() ' Get the next image file name         
        DrawOffScreenImage()
        Timer1.Interval = 5000
        Invalidate()
End Sub

Private Sub DrawOffScreenImage()
        bmImageFile = bmImageFile.FromFile(strNextImage)
        bmOffScreenImage = New Bitmap(Me.Width, Me.Height)
        gpOffScreenGraphics = Graphics.FromImage(bmOffScreenImage)
        
       'Do some graphics operations on goOffScreenGraphics
       'like the following
       gpOffScreenGraphics.DrawImage(bmImageFile, 0, 0, bmImageFile.width * 1.3 , bmImageFile.height * 1.3 )

       gpOffScreenGraphics.Dispose()
End Sub

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            ImageTransition(e.Graphics)
End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
         DrawOffScreenImage()
         Invalidate()    
End Sub

Private Sub ImageTransition(ByVal gpFormGraphics As Graphics)
                Dim w As Integer = CInt(Me.Width / 2)
                Dim h As Integer = CInt(Me.Height / 2)

                For i = 0 To w                    
                    If i <= h Then
                        gpFormGraphics.DrawImage(bmOffScreenImage, w - i, h - i, New Rectangle(w - i, h - i, 2 * i, 1), GraphicsUnit.Pixel)
                        gpFormGraphics.DrawImage(bmOffScreenImage, w - i, h + i - 1, New Rectangle(w - i, h + i - 1, 2 * i, 1), GraphicsUnit.Pixel)
                        'Debug.Print(i & " " & CType(Me.Width / 2, Integer) - i & " " & CType(Me.Height / 2, Integer) + i)
                    End If
                 Next i
End Sub

It still behaves the exact same way as before !! I'm totally lost here !!

Any input/help in this regard will be highly appreciated.

Thanks.
 
Back
Top