A paint event question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • hamil

    #1

    A paint event question

    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.CreateGraphi cs
    gr.Interpolatio nMode = Drawing2D.Inter polationMode.Hi ghQualityBicubi c
    gr.DrawImage(bm , New Rectangle(0, 0, 400, 500))[color=blue][color=green][color=darkred]
    >>> can I save the image here[/color][/color][/color]
    End Sub

    sub Page1_paint[color=blue][color=green][color=darkred]
    >>>>> and restore it here[/color][/color][/color]
    end sub

    sub Page1_Closing
    gr.dispose
    end sub
  • Bart Mermuys

    #2
    Re: A paint event question

    Hi,

    "hamil" <hamil@discussi ons.microsoft.c om> wrote in message
    news:EDE7C508-8803-46E5-ADEE-6E85326448A6@mi crosoft.com...[color=blue]
    > 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[/color]

    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.
    [color=blue]
    > 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.[/color]

    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.Inte rpolationMode =
    Drawing2D.Inter polationMode.Hi ghQualityBicubi c
    e.DrawImage(bm, New Rectangle(0, 0, 400, 500))
    End If
    End sub

    Sub Page1_Closing
    bm.Dispose
    bm = Nothing
    End Sub

    HTH,
    Greetings


    Comment

    • hamil

      #3
      Re: A paint event question



      "Bart Mermuys" wrote:
      [color=blue]
      > Hi,
      >
      > "hamil" <hamil@discussi ons.microsoft.c om> wrote in message
      > news:EDE7C508-8803-46E5-ADEE-6E85326448A6@mi crosoft.com...[color=green]
      > > 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[/color]
      >
      > 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.
      >[color=green]
      > > 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.[/color]
      >
      > 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.Inte rpolationMode =
      > Drawing2D.Inter polationMode.Hi ghQualityBicubi c
      > e.DrawImage(bm, New Rectangle(0, 0, 400, 500))
      > End If
      > End sub
      >
      > Sub Page1_Closing
      > bm.Dispose
      > bm = Nothing
      > End Sub
      >
      > HTH,
      > Greetings
      >
      >
      >[/color]
      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.

      Comment

      • Bart Mermuys

        #4
        Re: A paint event question

        Hi,

        "hamil" <hamil@discussi ons.microsoft.c om> wrote in message
        news:D44F685A-EFE6-4E4F-B004-E8690DF47835@mi crosoft.com...[color=blue]
        >
        >
        > "Bart Mermuys" wrote:
        >[color=green]
        >> Hi,
        >>
        >> "hamil" <hamil@discussi ons.microsoft.c om> wrote in message
        >> news:EDE7C508-8803-46E5-ADEE-6E85326448A6@mi crosoft.com...[color=darkred]
        >> > 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[/color]
        >>
        >> 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.
        >>[color=darkred]
        >> > 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.[/color]
        >>
        >> 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.Inte rpolationMode =
        >> Drawing2D.Inter polationMode.Hi ghQualityBicubi c
        >> e.DrawImage(bm, New Rectangle(0, 0, 400, 500))
        >> End If
        >> End sub
        >>
        >> Sub Page1_Closing
        >> bm.Dispose
        >> bm = Nothing
        >> End Sub
        >>
        >> HTH,
        >> Greetings
        >>
        >>
        >>[/color]
        > 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.[/color]

        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.FromIm age( bm )
        gfx.Interpolati onMode = Drawing2D.Inter polationMode.Hi ghQualityBicubi c
        gfx.DrawImage(f ileBitmap, New Rectangle(0, 0, 400, 500))
        gfx.Dispose()

        ' dispose file bitmap
        fileBitmap.Disp ose();

        ' trigger onpaint
        Invalidate()
        End Sub

        Sub Page1_paint
        If ( Not bm Is Nothing ) Then
        e.Graphics.Draw ImageUnscaled(b m, 0, 0, 0, 0, 0 )
        End If
        End Sub

        Sub Page1_Closing
        bm.Dispose
        bm = Nothing
        End Sub

        HTH,
        Greetings

        [color=blue]
        >
        > Any thoughts here? Maybe this cannot be done in VB.
        >
        > Hamil.
        >[/color]


        Comment

        • Dennis

          #5
          Re: A paint event question

          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?
          --
          Dennis in Houston


          "Bart Mermuys" wrote:
          [color=blue]
          > Hi,
          >
          > "hamil" <hamil@discussi ons.microsoft.c om> wrote in message
          > news:D44F685A-EFE6-4E4F-B004-E8690DF47835@mi crosoft.com...[color=green]
          > >
          > >
          > > "Bart Mermuys" wrote:
          > >[color=darkred]
          > >> Hi,
          > >>
          > >> "hamil" <hamil@discussi ons.microsoft.c om> wrote in message
          > >> news:EDE7C508-8803-46E5-ADEE-6E85326448A6@mi crosoft.com...
          > >> > 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.Inte rpolationMode =
          > >> Drawing2D.Inter polationMode.Hi ghQualityBicubi c
          > >> e.DrawImage(bm, New Rectangle(0, 0, 400, 500))
          > >> End If
          > >> End sub
          > >>
          > >> Sub Page1_Closing
          > >> bm.Dispose
          > >> bm = Nothing
          > >> End Sub
          > >>
          > >> HTH,
          > >> Greetings
          > >>
          > >>
          > >>[/color]
          > > 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.[/color]
          >
          > 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.FromIm age( bm )
          > gfx.Interpolati onMode = Drawing2D.Inter polationMode.Hi ghQualityBicubi c
          > gfx.DrawImage(f ileBitmap, New Rectangle(0, 0, 400, 500))
          > gfx.Dispose()
          >
          > ' dispose file bitmap
          > fileBitmap.Disp ose();
          >
          > ' trigger onpaint
          > Invalidate()
          > End Sub
          >
          > Sub Page1_paint
          > If ( Not bm Is Nothing ) Then
          > e.Graphics.Draw ImageUnscaled(b m, 0, 0, 0, 0, 0 )
          > End If
          > End Sub
          >
          > Sub Page1_Closing
          > bm.Dispose
          > bm = Nothing
          > End Sub
          >
          > HTH,
          > Greetings
          >
          >[color=green]
          > >
          > > Any thoughts here? Maybe this cannot be done in VB.
          > >
          > > Hamil.
          > >[/color]
          >
          >
          >[/color]

          Comment

          • Bart Mermuys

            #6
            Re: A paint event question

            Hi,

            "Dennis" <Dennis@discuss ions.microsoft. com> wrote in message
            news:3A9F8F5F-723D-46F8-9557-33639A2B93C5@mi crosoft.com...[color=blue]
            > 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?[/color]

            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
            [color=blue]
            > --
            > Dennis in Houston
            >
            >
            > "Bart Mermuys" wrote:
            >[color=green]
            >> Hi,
            >>
            >> "hamil" <hamil@discussi ons.microsoft.c om> wrote in message
            >> news:D44F685A-EFE6-4E4F-B004-E8690DF47835@mi crosoft.com...[color=darkred]
            >> >
            >> >
            >> > "Bart Mermuys" wrote:
            >> >
            >> >> Hi,
            >> >>
            >> >> "hamil" <hamil@discussi ons.microsoft.c om> wrote in message
            >> >> news:EDE7C508-8803-46E5-ADEE-6E85326448A6@mi crosoft.com...
            >> >> > 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.Inte rpolationMode =
            >> >> Drawing2D.Inter polationMode.Hi ghQualityBicubi c
            >> >> 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.[/color]
            >>
            >> 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.FromIm age( bm )
            >> gfx.Interpolati onMode = Drawing2D.Inter polationMode.Hi ghQualityBicubi c
            >> gfx.DrawImage(f ileBitmap, New Rectangle(0, 0, 400, 500))
            >> gfx.Dispose()
            >>
            >> ' dispose file bitmap
            >> fileBitmap.Disp ose();
            >>
            >> ' trigger onpaint
            >> Invalidate()
            >> End Sub
            >>
            >> Sub Page1_paint
            >> If ( Not bm Is Nothing ) Then
            >> e.Graphics.Draw ImageUnscaled(b m, 0, 0, 0, 0, 0 )
            >> End If
            >> End Sub
            >>
            >> Sub Page1_Closing
            >> bm.Dispose
            >> bm = Nothing
            >> End Sub
            >>
            >> HTH,
            >> Greetings
            >>
            >>[color=darkred]
            >> >
            >> > Any thoughts here? Maybe this cannot be done in VB.
            >> >
            >> > Hamil.
            >> >[/color]
            >>
            >>
            >>[/color][/color]


            Comment

            • Bart Mermuys

              #7
              Re: A paint event question

              Hi,

              <snipped>
              [color=blue][color=green]
              >> 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.[/color]
              >
              > 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.FromIm age( bm )
              > gfx.Interpolati onMode = Drawing2D.Inter polationMode.Hi ghQualityBicubi c
              > gfx.DrawImage(f ileBitmap, New Rectangle(0, 0, 400, 500))
              > gfx.Dispose()
              >
              > ' dispose file bitmap
              > fileBitmap.Disp ose();
              >
              > ' trigger onpaint
              > Invalidate()
              > End Sub[/color]

              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.Draw Image(bm, e.ClipRectangle , e.ClipRectangle ,
              GraphicsUnit.Pi xel)
              End If
              End Sub

              HTH,
              Greetings
              [color=blue]
              >
              > Sub Page1_Closing
              > bm.Dispose
              > bm = Nothing
              > End Sub
              >
              > HTH,
              > Greetings
              >
              >[color=green]
              >>
              >> Any thoughts here? Maybe this cannot be done in VB.
              >>
              >> Hamil.
              >>[/color]
              >
              >[/color]


              Comment

              • hamil

                #8
                RE: A paint event question

                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.








                "hamil" wrote:
                [color=blue]
                > 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.CreateGraphi cs
                > gr.Interpolatio nMode = Drawing2D.Inter polationMode.Hi ghQualityBicubi c
                > gr.DrawImage(bm , New Rectangle(0, 0, 400, 500))[color=green][color=darkred]
                > >>> can I save the image here[/color][/color]
                > End Sub
                >
                > sub Page1_paint[color=green][color=darkred]
                > >>>>> and restore it here[/color][/color]
                > end sub
                >
                > sub Page1_Closing
                > gr.dispose
                > end sub[/color]

                Comment

                Working...