# Visual Basic > Visual Basic 6 and Earlier >  GDI+ bitmap vs GDI+ image

## Elroy

Does anyone have a thorough grasp on the difference between these two, and why I might choose one over the other, and what circumstances a hGdipImage would be appropriate and when an hGdipBitmap would be appropriate?

----------


## Elroy

Also, as a secondary question, how would one convert an hGdipImage to an hGdipBitmap?  I don't see any GDI+ call to do that.  Also, I'd be interested in the vice-versa as well.

----------


## dilettante

I haven't looked hard for a long time but I believe that in many ways the GDI "Image" is a container interface that may house various things such as Bitmaps with their own more specific interfaces.

A lot of the flat API calls in the "Image" category will silently accept a "Bitmap" handle.  Some don't make sense, but those that do work just fine.

Think of "Image" as _a little bit like_ an OLE Picture (StdPicture) that can contain bitmaps, icons, metafiles, etc.

----------


## Elroy

> A lot of the flat API calls in the "Image" category will silently accept a "Bitmap" handle.


And several of the API calls in the "Bitmap" category will accept hGdipImage handles.  That's what makes any distinction difficult to understand.

However, ...




> Think of "Image" as a little bit like an OLE Picture (StdPicture) that can contain bitmaps, icons, metafiles, etc.


... that does make some sense.

--------------

So, that still leaves these questions outstanding:

If hGdipImage is a container (that may have a hGdipBitmap in it), how do we get the hGdipBitmap out of it?

And, if we have an hGdipBitmap, how would we go about putting it into an hGdipImage container?

Not sure I'll need either of those (especially since they're fairly interchangeable in the API calls), but it'd still be nice to know.

----------


## dilettante

I think you might be pushing the container analogy.  It seems to really be about inheritance.

More likely what we have behind the handle is some sort of struct with a header indicating "type" information and then a set of pointers to other things like some equivalent of BITMAPINFO and the raw bits and such.

The Flat API is so close to the inner workings that we're probably lucky it was ever documented at all, and thus so poorly.  There just isn't much aside from a brief description and a link to the docs on the related C++ API class for us to puzzle over.

I suspect Microsoft expected C programmers to gut through using the C++ API as well.  That drastically slowed adoption, so the Flat API got documented, er, described, er, listed out... mainly for them.

The C++ API docs do have snippets like this though:




> GDI+ provides the Image class for working with raster images (bitmaps) and vector images (metafiles). The Bitmap class and the Metafile class both inherit from the Image class. The Bitmap class expands on the capabilities of the Image class by providing additional methods for loading, saving, and manipulating raster images. The Metafile class expands on the capabilities of the Image class by providing additional methods for recording and examining vector images.

----------


## Elroy

> I think you might be pushing the container analogy.  It seems to really be about inheritance.
> 
> More likely what we have behind the handle is some sort of struct with a header indicating "type" information and then a set of pointers to other things like some equivalent of BITMAPINFO and the raw bits and such.
> 
> The Flat API is so close to the inner workings that we're probably lucky it was ever documented at all, and thus so poorly.  There just isn't much aside from a brief description and a link to the docs on the related C++ API class for us to puzzle over.
> 
> I suspect Microsoft expected C programmers to gut through using the C++ API as well.  That drastically slowed adoption, so the Flat API got documented, er, described, er, listed out... mainly for them.
> 
> The C++ API docs do have snippets like this though:


*nods*  Thanks for that though.   :Smilie: 

It's sort of a shame this didn't get more widely adopted, as it seems to have some very nice functionality ... if only it had a bit more documentation.  Wandering around in the dark, seeing what works and what doesn't, isn't terribly fun.

----------


## dilettante

Maybe somebody else knows a lot more.  I'm certainly no expert.

I try to suck any scraps meat off the documentation bones and then I'm down to trial and error.  Sounds like you have found yourself in a similar spot.

It begins to feel like some phase of the "Mad Max" progression where we are living off the trash piles of a former civilization that is barely remembered except through verbal tradition.

----------


## Niya

In GDI+'s .Net wrappers, Image serves as a base class for Bitmap and another type called Metafile. We can use Image when the we don't care whether it's a Bitmap or Metafile as it can represent both. It's probably the same deal using the GDI+ API directly. 

So Bitmap when we only want to deal with Bitmaps, Metafile when we only want to deal with Metafiles and Image when we want to deal with both. Eg:-


```
'Takes an Bitmap or Metafile
Sub DoSomething(ByVal img As Image)
''''
End Sub
```



```
'Takes only a Bitmap object
Sub DoSomething(ByVal img As Bitmap)
''''
End Sub
```

----------


## Argus19

It turns out something like this:



> Image and Bitmap are the same





> create a Bitmap and get the Graphics associated with it. When drawing to this Graphics, everything will be mapped to this Bitmap. See GdipGetImageGraphicsContext function.





> The Image class is intended for storing images in the GDI+ library. Its descendants, the Bitmap and Metafile classes, implement respectively the functionality for working with raster and vector images. By the way, the .NET Framework SDK documentation states that the Image class is also a descendant of the Icon class, but this is not true: it is inherited from System.MarshalByRefObject. The Icon class does not exist in the GDI+ class hierarchy for C++ (all the necessary tools for working with icons are in the Bitmap).

----------


## The trick

Image can represent multi frame pictures.

----------


## Elroy

Ahhh, ok, it's finally getting into my head.  Some of the GDI+ documentation suggested that bitmap was more powerful/flexible than image ... MSDN:




> The Bitmap class expands on the capabilities of the Image class...


But it appears the exact opposite is true:

Image can contain either bitmaps or metafile whereas a bitmap is just a bitmap.An image handle will work with most of the GDI+ bitmap calls (particularly if the image contains a bitmap).An image can deal with multi-frame files (GIF, PNG, etc) whereas a bitmap can't.

However, if we're dealing strictly with single frame bitmaps, I suspect managing a bitmap handle is slightly faster than managing an image handle.  So, if we're dealing strictly with these bitmaps, that might be the way to go.

----------


## dilettante

If you are trying to create a GDI+ wrapper library in VB6 you are stuck before you get started.  GDI+'s C++ API is heavily reliant on class inheritance and overloaded members.

A Bitmap is a special case of Image.  As such, a Bitmap also has a Frames collection, it just has a Count of 1.

----------


## Elroy

> If you are trying to create a GDI+ wrapper library in VB6 you are stuck before you get started.  GDI+'s C++ API is heavily reliant on class inheritance and overloaded members.
> 
> A Bitmap is a special case of Image.  As such, a Bitmap also has a Frames collection, it just has a Count of 1.


I'm not sure what I'm trying to do.  At most, I'm really just trying to make some intuitive tools for working with 32bpp RGBA PNG files, and using the GDI+ to do it.  Anything I feel is useful, I'll post it.

Part of the trouble is that full-blown paint/photoshop programs like the terminology of a "mask" rather than just directly operating on the alpha channel, and that's quite annoying to me.  Maybe I'll feel differently someday, but I don't care anything about having multiple masks.  

I might eventually get into layers, but that's far down the road.

And I don't have a specific objective in mind, which is making it a bit difficult to stay motivated.

----------


## dilettante

The ones that get me are translucency and antialiasing.  I've never tried using utilities that support those but they look complicated.  I'm just not sure how to indicate the "alpha gradients" desired, fading out edges or doing translucency fills and such.

----------


## Niya

> Ahhh, ok, it's finally getting into my head.  Some of the GDI+ documentation suggested that bitmap was more powerful/flexible than image ... MSDN:
> 
> But it appears the exact opposite is true:


No, you're looking at it wrong. You have to think in terms of inheritance. Inheritance isn't about making something more powerful or flexible. It's about grouping common functionality. A Bitmap is a type of Image and a Metafile is also a type of Image. The functionality common to both will be implemented in Image. Bitmap will add the things that are relevant only to Bitmap and Metafile would add things relevant to only Metafile.

----------


## dilettante

That's sort of why I brought up interfaces earlier, since that's as close as we can get to polymorphism in COM/VB.

The docs discuss some examples of this.  Something like an Animal interface that a Pig, Fish, and Bird class all implement.

Another might be something like a common Plugin interface that several concrete classes implement in addition to their own specialized interfaces.

----------


## Niya

> That's sort of why I brought up interfaces earlier, since that's as close as we can get to polymorphism in COM/VB.
> 
> The docs discuss some examples of this.  Something like an Animal interface that a Pig, Fish, and Bird class all implement.
> 
> Another might be something like a common Plugin interface that several concrete classes implement in addition to their own specialized interfaces.


Exactly!

----------


## SomeYguy

I've found that most of the GDI+ functions which I normally use for simple shape drawing and raster imaging are straightforward and work well. Indeed, most all of the user interface elements of all of my programs are created and rendered at runtime using GDI+ and I'm pleased as can be with it. Several years ago I wrote a simple but handy set of wrappers (one for drawing, one for imaging)  which I will post to the codebank when I get a chance. Nothing fancy ala LaVolpe but just small, simple and (I hope) useful.

Regarding original question, my stuff uses pretty much 100% GDI+ bitmaps so I guess I'll need to experiment with GDI+ images  :Smilie: 


EDIT: I stand corrected, my imaging wrapper uses a bit of both.

----------


## yokesee

> I've found that most of the GDI+ functions which I normally use for simple shape drawing and raster imaging are straightforward and work well. Indeed, most all of the user interface elements of all of my programs are created and rendered at runtime using GDI+ and I'm pleased as can be with it. Several years ago I wrote a simple but handy set of wrappers (one for drawing, one for imaging)  which I will post to the codebank when I get a chance. Nothing fancy ala LaVolpe but just small, simple and (I hope) useful.
> 
> Regarding original question, my stuff uses pretty much 100% GDI+ bitmaps so I guess I'll need to experiment with GDI+ images 
> 
> 
> EDIT: I stand corrected, my imaging wrapper uses a bit of both.


Please any contribution is welcome.
 :Smilie:

----------

