Different ways for persistent graphics in VB.net

  • Thread starter Thread starter C
  • Start date Start date
The graphics object is a collection of drawing (and other) methods gathered
together into a single object.  When you create the graphics object you
'connect' it to a drawing surface - for instance, a bitmap.  When you
execute a drawing method using the graphics object, that method is executed
using the drawing surface associated with the object.  The graphics object
is not an image or a portion of an image.  

In other words, you are saying that anything drawn on the graphics
object gets drawn on the image as well.

Or if the graphics object was created for a form, it gets drawn to the
form as well. No, I don't think I understand this. I think some
operation is necessary to move my drawing lines from the graphics
object to the image or the form. Like DrawImage?

This stuff is explained in hundreds of Internet sites with a recipe
approach, rather than explaining the fundamentals of what happens
inside the graphics object. The graphics object is nothing more than
properties and associated methods (subroutines).
All graphics objects must be
associated with a drawing surface (such as an image, a screen, a printer)
because you can only create a graphics object by using a method that
connects it to the drawing surface you want to use it with.

So I can't create a graphics object for a form and put it in an image?
Is this where CopyFromScreen or something like that is necessary?
 
Right, the paint command's are the methods of the Graphics object.


I'm not sure about the internals. However, consider the Graphics object
being a tool to draw on something (Image, Form, Printer...). That
something is the canvas, the destination. Usually output is done on
devices like the screen (to a window) or a printer. An image is just an
alternative output destination.

IOW: The Graphics object is the painter. The device or an image is the
painting. You can have the painter paint on the painting by calling one
of the painter's Draw* methods.

Thanks. I think this has gradually become clearer to me.
 
On 9 elo, 13:38, "Jeff Richards" <[email protected]> wrote:
In other words, you are saying that anything drawn on the graphics
object gets drawn on the image as well.

No, that is not what he said. You do not draw on the graphics object.
You use the graphics object to draw on the canvas, which might be a
bitmap, a form, a printer, etc.
Or if the graphics object was created for a form, it gets drawn to the
form as well. No, I don't think I understand this. I think some
operation is necessary to move my drawing lines from the graphics
object to the image or the form. Like DrawImage?

See above. The graphics object does not contain any kind of drawing.
It is a tool to draw on the canvas to which it is associated.
So I can't create a graphics object for a form and put it in an image?
Is this where CopyFromScreen or something like that is necessary?

Saying "create a graphics object for a form and put it in an image"
makes no sense. The graphics object does not contain any image data,
the associated canvas (bitmap, form, etc.) contains the image data. It
may be possible to take image data from the canvas associated with the
graphics object and move all or part of it to a different canvas, but
that has nothing to do with the graphics object.

Again, the graphics object is just a set of painting tools. It is
used to paint on the associated canvas, it does not contain any image
data.
 
It helps a little bit. I don't see the logic in it, however.
Graphics.FromImage creates a graphics object and we can draw lines on
it, but how does the image get updated? Unless the image "contains"
the graphics object with all its methods and properties, or the other
way round, it should be necessary to give some instruction to myImage
to update itself from the graphics object. This is not being done, and
I don't see this as very logical. Graphics.DrawImage in Form_Paint is
simply displaying on the Form what it has in the image. So where does
myImage get updated when I draw in g?

You are not "drawing in g". Assuming that g is a Graphics object
created by calling FromImage(myImage), then that graphics object is
associated with myImage. Every time you make a drawing call on g,
that call is executed on myImage, it is not executed on g.

Again, a graphics object is a set of painting tools that operate on
the associated canvas. When the graphics object is created by
FromImage(myImage), the canvas is myImage. When the graphics object
is the one passed to the Paint event of a form, the canvas is the
form.
 
--
Jeff Richards
MS MVP (Windows - Shell/User)
In other words, you are saying that anything drawn on the graphics
object gets drawn on the image as well.

You don't draw ON a graphics object - you draw WITH a graphics object. It's
the tool used for drawing. You draw on the surface (such as a bitmap) that
is associated with the graphics object.
Or if the graphics object was created for a form, it gets drawn to the
form as well. No, I don't think I understand this. I think some
operation is necessary to move my drawing lines from the graphics
object to the image or the form. Like DrawImage?

If the graphics objet was created for a form then the drawing methods
executed with the graphics object will result in changes to the form. The
graphics object is not an image and and does not contain the lines you draw.
There are no the lines 'on' the graphics object to be 'moved' - there are
only the lines on the form drawn there by the graphics object when you
instructed it using a DrawLines method.
This stuff is explained in hundreds of Internet sites with a recipe
approach, rather than explaining the fundamentals of what happens
inside the graphics object. The graphics object is nothing more than
properties and associated methods (subroutines).

You need to examine the code line by line, in conjunction with the
descriptions of the classes and their methods, to get the best out of those
examples.
So I can't create a graphics object for a form and put it in an image?
Is this where CopyFromScreen or something like that is necessary?

You can create a graphics object for anything that can be drawn on, but you
do not 'put' a graphics object in an image. You use the graphics object to
draw on an image. CopyFromScreen is just another way of drawing something.
 
It helps a little bit. I don't see the logic in it, however.
Graphics.FromImage creates a graphics object and we can draw lines on
it, but how does the image get updated? Unless the image "contains"
the graphics object with all its methods and properties, or the other>
way round, it should be necessary to give some instruction to myImage
to update itself from the graphics object. This is not being done, and
I don't see this as very logical. Graphics.DrawImage in Form_Paint is
simply displaying on the Form what it has in the image. So where does
myImage get updated when I draw in g?

There is some logic in it, but the names aren't always obvious.

The graphics object is a toolkit, and the tools that can be used vary
somewhat according to the type of drawing surface. Therefore, when the
toolkit (the graphics object) is created it must know the drawing surface
that it is being used with. That's why every graphics object must be
associated with a drawing surface. The 'From' in Graphics.FromImage is a
slightly obscure way of saying "The information about exactly how to
construct this toolkit is to be taken from this image".
 
No, that is not what he said.  You do not draw on the graphics object.
You use the graphics object to draw on the canvas, which might be a
bitmap, a form, a printer, etc.


See above.  The graphics object does not contain any kind of drawing.
It is a tool to draw on the canvas to which it is associated.


Saying "create a graphics object for a form and put it in an image"
makes no sense.  The graphics object does not contain any image data,
the associated canvas (bitmap, form, etc.) contains the image data. It
may be possible to take image data from the canvas associated with the
graphics object and move all or part of it to a different canvas, but
that has nothing to do with the graphics object.

Again, the graphics object is just a set of painting tools.  It is
used to paint on the associated canvas, it does not contain any image
data.

Clear. Graphics object contains just the methods to use to draw on the
associated canvas. The graphics object is not storing the vector
graphics; a metafile can. A bitmap image will store the bitmap of the
drawn image, and not the vector graphics. The graphics object does NOT
contain the image in it.

But we can put this stuff from an image onto a Form if we want by
DrawImage.
 
--
Jeff Richards



You don't draw ON a graphics object - you draw WITH a graphics object.  It's
the tool used for drawing.  You draw on the surface (such as a bitmap) that
is associated with the graphics object.


If the graphics objet was created for a form then the drawing methods
executed with the graphics object will result in changes to the form.  The
graphics object is not an image and and does not contain the lines you draw.
There are no the lines 'on' the graphics object to be 'moved' - there are
only the lines on the form drawn there by the graphics object when you
instructed it using a DrawLines method.


You need to examine the code line by line, in conjunction with the
descriptions of the classes and their methods, to get the best out of those
examples.


You can create a graphics object for anything that can be drawn on, but you
do not 'put' a graphics object in an image.  You use the graphics object to
draw on an image.   CopyFromScreen is just another way of drawing something.

Yes, now it is clear.
 
There is some logic in it, but the names aren't always obvious.

The graphics object is a toolkit, and the tools that can be used vary
somewhat according to the type of drawing surface.  Therefore, when the
toolkit (the graphics object) is created it must know the drawing surface
that it is being used with. That's why every graphics object must be
associated with a drawing surface. The 'From' in Graphics.FromImage is a
slightly obscure way of saying "The information about exactly how to
construct this toolkit is to be taken from this image".

Thanks.
 
What I thought is that I would produce another plot (one
smaller one to show on the screen and another for printing)
with a huge bitmap to allow 300 dpi for about 15 cm by
8 cm (about 1800 pixels by 1000 pixels) which can be
saved as a bitmap and still be printed with fairly good
clarity. If 600 dpi is required, that too would be
feasible with 4 times as many pixels [3600 x 2000].
A standard full colour (24 bits per pixel) bitmap file of a size 3600 x2000
pixels would indeed be feasible, but it would be extremely large (about20
MB) for what is effectively a copy of a small 15 x 8 cm drawing. Also you
would need to carefully consider the different line widths etc that would be
required for creating the bitmap so that they are suitable for drawing onto
a high resolution device. Converting such a bitmap to a jpeg would reduce
the file size somewhat, but at the expense of quality. On the other hand a
metafile (.emf) would be very small by comparison (up to a thousand times
smaller or even more, depending on the complexity of the drawing), and would
contain exactly the same drawing but in a way that allows it to be printed
at any size you desire to any output device whilst maintaining the full
output quality of the device to which you are drawing it.
As I mentioned in my previous posts I am a VB6 programmer myself and I am
really just "nosing about" in here, so I have never written any code to
create metafiles in VB.Net. I have written such code in VB6 though, but
because VB6 does not have any native metafile functions it is necessaryto
create one using the CreateEnhMetafile API function and draw into the handle
it returns using pens and brushes that need to be created using the various
CreatePen, CreateBrush and CreateFont etc API functions (due to the fact
that standard VB6 drawing methods cannot be used on a metafile handle
because VB6 knows nothing about them). In VB6 this is a little bit complex
but it is actually much simpler than it sounds once you have got the main
basic routine off the ground. However I'm pretty sure that VB.Net has native
functions to create and draw into metafiles and so VB.Net should do most of
that work for you. In fact I've just "Googled" for information on the
subject and this is the first hit I got. It looks like it could be exactly
what you need:

Mike

It seems to be as simple as this:

' Make a metafile that can work with the hDC.
    Dim mf As New Metafile(txtFile.Text, hdc, _
        New Rectangle(0, 0, 210, 210), _
        MetafileFrameUnit.Pixel)

    ' Make a Graphics object to work with the metafile.
    Dim mf_gr As Graphics = Graphics.FromImage(mf)

    ' Draw on the metafile.
    Dim the_pen As New Pen(Color.Blue, 5)
    mf_gr.DrawRectangle(the_pen, 5, 5, 190, 190)

The key is to create Graphics.FromImage(metafilename)
and then draw on it. Finally, it is saved as gr.DrawImage(mf, 0, 0)

See, VB.net does have some added value. They might be fooling us with
the name, but this new thing is worthwhile learning.- Piilota siteerattu teksti -

- Näytä siteerattu teksti -

Well, it is not as simple as that. I tried it now and find that the
Metafile class is not recognised by VB Express 2008. And there is no
simple way of saving a metafile. A windows API writes metafiles which
can be called, but it is not as simple as saving the file.

Metafiles would be convenient for me because much of my graphics is
plots of two or three kinds drawing lines and a little bit of text.
 

What I thought is that I would produce another plot (one
smaller one to show on the screen and another for printing)
with a huge bitmap to allow 300 dpi for about 15 cm by
8 cm (about 1800 pixels by 1000 pixels) which can be
saved as a bitmap and still be printed with fairly good
clarity. If 600 dpi is required, that too would be
feasible with 4 times as many pixels [3600 x 2000].
A standard full colour (24 bits per pixel) bitmap file of a size 3600 x 2000
pixels would indeed be feasible, but it would be extremely large (about 20
MB) for what is effectively a copy of a small 15 x 8 cm drawing. Also you
would need to carefully consider the different line widths etc that would be
required for creating the bitmap so that they are suitable for drawing onto
a high resolution device. Converting such a bitmap to a jpeg would reduce
the file size somewhat, but at the expense of quality. On the other hand a
metafile (.emf) would be very small by comparison (up to a thousand times
smaller or even more, depending on the complexity of the drawing), and would
contain exactly the same drawing but in a way that allows it to be printed
at any size you desire to any output device whilst maintaining the full
output quality of the device to which you are drawing it.
Metafiles would be nice, but there do not seem to be
any easy ways of writing them from VB. Any information
on this would be welcome.
As I mentioned in my previous posts I am a VB6 programmer myself and I am
really just "nosing about" in here, so I have never written any code to
create metafiles in VB.Net. I have written such code in VB6 though, but
because VB6 does not have any native metafile functions it is necessary to
create one using the CreateEnhMetafile API function and draw into the handle
it returns using pens and brushes that need to be created using the various
CreatePen, CreateBrush and CreateFont etc API functions (due to the fact
that standard VB6 drawing methods cannot be used on a metafile handle
because VB6 knows nothing about them). In VB6 this is a little bit complex
but it is actually much simpler than it sounds once you have got the main
basic routine off the ground. However I'm pretty sure that VB.Net has native
functions to create and draw into metafiles and so VB.Net should do most of
that work for you. In fact I've just "Googled" for information on the
subject and this is the first hit I got. It looks like it could be exactly
what you need:

Mike

It seems to be as simple as this:

' Make a metafile that can work with the hDC.
    Dim mf As New Metafile(txtFile.Text, hdc, _
        New Rectangle(0, 0, 210, 210), _
        MetafileFrameUnit.Pixel)

    ' Make a Graphics object to work with the metafile.
    Dim mf_gr As Graphics = Graphics.FromImage(mf)

    ' Draw on the metafile.
    Dim the_pen As New Pen(Color.Blue, 5)
    mf_gr.DrawRectangle(the_pen, 5, 5, 190, 190)

The key is to create Graphics.FromImage(metafilename)
and then draw on it. Finally, it is saved as gr.DrawImage(mf, 0, 0)

See, VB.net does have some added value. They might be fooling us with
the name, but this new thing is worthwhile learning.- Piilota siteerattu teksti -

- Näytä siteerattu teksti -

Well, it is not as simple as that. I tried it now and find that the
Metafile class is not recognised by VB Express 2008. And there is no

The metafile class has been in all versions of the .net framework. You need
to add:

Imports System.Drawing.Imaging

to the top of your code - and make sure you are referencing
System.Drawing.dll (though, if this is a windows forms project you will be by
default).
 
Well, it is not as simple as that. I tried it now and find that
the Metafile class is not recognised by VB Express 2008.
And there is no simple way of saving a metafile. A windows
API writes metafiles which can be called, but it is not as
simple as saving the file.

Actually the API and the VB.Net native metafile functions are both capable
of creating either a memory metafile or a disk based metafile. Since you are
understandably using the VB.Net native metafile methods you'll need to add
the System.Drawing reference as already suggested by Tom and you'll then see
that the code at the link I posted creates a disk based metafile for you.

Mike
 
Clear. Graphics object contains just the methods to use to draw on the
associated canvas. The graphics object is not storing the vector
graphics; a metafile can. A bitmap image will store the bitmap of the
drawn image, and not the vector graphics. The graphics object does NOT
contain the image in it.
But we can put this stuff from an image onto a Form if we want by
DrawImage.

DrawImage will copy an image (eg, a bitmap) onto the form, but the metafile
does not contain an image. The metafile contains drawing instructions
(vectors, fills, patterns, clipping, scaling etc). To 'put' a metafile on a
form you enumerate it - that is, you 'play back' the metafile instructions
in sequence, and it is these instructions that draw the image on the form.
 
Back
Top