A paint event question

G

Guest

The following code will display a tif file on a form. When another form is
moved over the tif image, the tif image is erased where the form was moved.
A paint event occurs when this happens. My question is..how would I save the
tif images as soon as it is initially painted, and then restore the image in
a paint event. It seems to me that there should be some sort of a SaveImage
method and a RestoreImage method that would be fast. Note: Page1 is the form
name, and FileName is passed from a routine on another form.

Public Filename as string
dim gr as graphics

Public Sub DrawTif()
Dim bm As Bitmap

bm = Bitmap.FromFile(FileName)

gr = Me.CreateGraphics
gr.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
gr.DrawImage(bm, New Rectangle(0, 0, 400, 500))End Sub

sub Page1_paintend sub

sub Page1_Closing
gr.dispose
end sub
 
B

Bart Mermuys

Hi,

hamil said:
The following code will display a tif file on a form. When another form is
moved over the tif image, the tif image is erased where the form was
moved.
A paint event occurs when this happens. My question is..how would I save
the
tif images as soon as it is initially painted, and then restore the image
in
a paint event. It seems to me that there should be some sort of a
SaveImage

But why would you want to save and restore it, it is already in a Bitmap,
just (re)draw it inside OnPaint. Also, never store a Graphics object
obtained with CreateGraphics, you must always Dispose it before the
eventhandler finishes.

See code below.
method and a RestoreImage method that would be fast. Note: Page1 is the
form
name, and FileName is passed from a routine on another form.

Public Filename as String
Dim bm As Bitmap

Public Sub DrawTif()
bm = Bitmap.FromFile(FileName)
End Sub

Sub Page1_paint
If ( Not bm Is Nothing ) Then
e.Graphics.InterpolationMode =
Drawing2D.InterpolationMode.HighQualityBicubic
e.DrawImage(bm, New Rectangle(0, 0, 400, 500))
End If
End sub

Sub Page1_Closing
bm.Dispose
bm = Nothing
End Sub

HTH,
Greetings
 
G

Guest

Bart Mermuys said:
Hi,



But why would you want to save and restore it, it is already in a Bitmap,
just (re)draw it inside OnPaint. Also, never store a Graphics object
obtained with CreateGraphics, you must always Dispose it before the
eventhandler finishes.

See code below.


Public Filename as String
Dim bm As Bitmap

Public Sub DrawTif()
bm = Bitmap.FromFile(FileName)
End Sub

Sub Page1_paint
If ( Not bm Is Nothing ) Then
e.Graphics.InterpolationMode =
Drawing2D.InterpolationMode.HighQualityBicubic
e.DrawImage(bm, New Rectangle(0, 0, 400, 500))
End If
End sub

Sub Page1_Closing
bm.Dispose
bm = Nothing
End Sub

HTH,
Greetings
Bert..

Your code works, but the paint event is slow. My image is a tif that was
originally an 8-1/2 X 11 page, black-white sheet scanned at 300 DPI, that
results in about 8,200,000 pixels. I use a Group four Fax compression that
makes the file about 50K bytes. The code " bm = bitmap.from file..." will
decompress and regenerate the 8,200,000 bit image. Since I am now displaying
the image on a form on by screen at about 1100 X 850 pixels, (935,000 bits),
interpolation must be used along with the scaling to get a good image. I am
pretty sure the scaling and interpolation is what is taking up most of the
time as this is done at every paint event.

It seems to me that there should be some way to scale, interpolate, and draw
the image to a buffer that is saved. Then at the paint event, the buffer
could be read and drawn without having to go through the scaling and
interpolation every time.

Any thoughts here? Maybe this cannot be done in VB.

Hamil.
 
B

Bart Mermuys

Hi,

hamil said:
Bert..

Your code works, but the paint event is slow. My image is a tif that was
originally an 8-1/2 X 11 page, black-white sheet scanned at 300 DPI, that
results in about 8,200,000 pixels. I use a Group four Fax compression that
makes the file about 50K bytes. The code " bm = bitmap.from file..." will
decompress and regenerate the 8,200,000 bit image. Since I am now
displaying
the image on a form on by screen at about 1100 X 850 pixels, (935,000
bits),
interpolation must be used along with the scaling to get a good image. I
am
pretty sure the scaling and interpolation is what is taking up most of the
time as this is done at every paint event.

It seems to me that there should be some way to scale, interpolate, and
draw
the image to a buffer that is saved. Then at the paint event, the buffer
could be read and drawn without having to go through the scaling and
interpolation every time.

You can draw the Bitmap from file into a memory Bitmap and then paint the
memory Bitmap inside onpaint, eg.:

Public Filename as String
Dim bm As Bitmap ' memory bitmap

Public Sub DrawTif()
Dim fileBitmap As Bitmap = Bitmap.FromFile(FileName)

' create memory bitmap
Dim gfx As Graphics = CreateGraphics()
bm = New Bitmap( 400, 500, gfx )
gfx.Dispose()

' draw file-bitmap scaled into memory-bitmap
gfx = Graphics.FromImage( bm )
gfx.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
gfx.DrawImage(fileBitmap, New Rectangle(0, 0, 400, 500))
gfx.Dispose()

' dispose file bitmap
fileBitmap.Dispose();

' trigger onpaint
Invalidate()
End Sub

Sub Page1_paint
If ( Not bm Is Nothing ) Then
e.Graphics.DrawImageUnscaled(bm, 0, 0, 0, 0, 0 )
End If
End Sub

Sub Page1_Closing
bm.Dispose
bm = Nothing
End Sub

HTH,
Greetings
 
G

Guest

If it's a large bitmap, wouldn't using BitBlt to copy the bitmap to the
graphics object passed in the paint event be much faster instead of drawimage?
 
B

Bart Mermuys

Hi,

Dennis said:
If it's a large bitmap, wouldn't using BitBlt to copy the bitmap to the
graphics object passed in the paint event be much faster instead of
drawimage?

BitBlt is GDI and DrawImage is GDI+, BitBlt will not scale but i guess you
could use it to transfer the memory Bitmap to the screen and maybe it will
be faster (i've heard GDI is faster then GDI+). Haven't tried it though.


HTH,
Greetings
 
B

Bart Mermuys

Hi,

You can draw the Bitmap from file into a memory Bitmap and then paint the
memory Bitmap inside onpaint, eg.:

Public Filename as String
Dim bm As Bitmap ' memory bitmap

Public Sub DrawTif()
Dim fileBitmap As Bitmap = Bitmap.FromFile(FileName)

' create memory bitmap
Dim gfx As Graphics = CreateGraphics()
bm = New Bitmap( 400, 500, gfx )
gfx.Dispose()

' draw file-bitmap scaled into memory-bitmap
gfx = Graphics.FromImage( bm )
gfx.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
gfx.DrawImage(fileBitmap, New Rectangle(0, 0, 400, 500))
gfx.Dispose()

' dispose file bitmap
fileBitmap.Dispose();

' trigger onpaint
Invalidate()
End Sub

Because Dennis asked something about the speed of DrawImage, i was thinking
that OnPaint could be faster if you do not draw the whole memory Bitmap but
just the invalidated part.

Sub Page1_paint
If ( Not bm Is Nothing ) Then
e.Graphics.DrawImage(bm, e.ClipRectangle, e.ClipRectangle,
GraphicsUnit.Pixel)
End If
End Sub

HTH,
Greetings
 
G

Guest

Thanks to both of you..

Barts first suggestion was much better than the way I was doing theonPaint.
Barts second suggestion was even better.

I looked into the BitBlt approach and I think it might be even faster but I
think this method would require me operating "outside" of VB.net exclusively,
i.e. require a Win API call.
Barts second suggeston where only the required part is repainted works very
well even on my slow 1 GHz Pentium III.

Thanks again.

Hamil.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top