views:

1300

answers:

2

I am writting code in c++, gdi+.

I make use of Image's GetThumbnail() method to get thumbnail. However, I need to convert it into HBITMAP. I know the following code can get GetHBITMAP:

Bitmap* img;
HBITMAP temp;
Color color;
img->GetHBITMAP(color, &temp); // if img is Bitmap*  this works well。

But how can I convert Image* into Bitmap* fast? Many thanks!

Actually, now I have to use the following method:

int width = sourceImg->GetWidth(); // sourceImg is Image*
int height = sourceImg->GetHeight();
Bitmap* Result;
result = new Bitmap(width, height,PixelFormat32bppRGB);
Graphics gr(result);
//gr.SetInterpolationMode(InterpolationModeHighQuality);
gr.DrawImage(&sourceImg,0,0,width,height);

I really don't know why they do not provide Image* - > Bitmap* method. but let GetThumbnail() API return a Image object....

A: 
Image* img = ???;
Bitmap* bitmap = new Bitmap(img);

Edit: I was looking at the.NET reference of GDI+, but here is how .NET implements that constructor.

using (Graphics graphics = null)
{
    graphics = Graphics.FromImage(bitmap);
    graphics.Clear(Color.Transparent);
    graphics.DrawImage(img, 0, 0, width, height);
}

All those function are avaliable in the C++ version of GDI+

Shay Erlichmen
I don't see any constructors for `Bitmap` that accept an `Image*`.
Rob Kennedy
me too~~ , Maybe in .NET it works, but c++ do not provide this constructor
+1  A: 

First you may try dynamic_cast as in many cases (if not most - at least in my use cases) Image indeed is a Bitmap. So

Image* img = getThumbnail( /* ... */ );
Bitmap* bitmap = dynamic_cast<Bitmap*>(img);
if(!bitmap)
    // getThumbnail returned an Image which is not a Bitmap. Convert.
else
    // getThumbnail returned a Bitmap so just deal with it.

However if somehow it is not (bitmap will be NULL) then you could try a more general solution.

For example save the Image to a COM IStream using Save method and then use Bitmap::FromStream to create Bitmap from that stream.

A simple COM IStream could be created using the CreateStreamOnHGlobal WinAPI function. However this is not efficient, especially for larger streams, but to test the idea it will do.

There are also other similar solutions which can be deduced from reading Image and Bitmap documentation.

Sadly I haven't tried it on my own (with Image which is not a Bitmap) so I am not entirely sure.

Adam Badura
It seems getThumbnail Method returns a Image* Object...
Actually, the code in the question is a perfectly good way of getting a Bitmap out of a generic Image.
Pavel Minaev
My answer gives potentially optimal solution since cost of dynamic_cast is small (compared to drawing/copying the image) and in most cases I think it will succeed.If not then either my version or the code in question (added after my answer) is a way to do. The code from question seems simpler and safer thou. However I am not sure how transparency will be handled by it.Also if possible it could be useful to refactor getThumbnail to return Bitmap* as it does not seem likely that it produces for example a vector graphic.
Adam Badura
I agree that for a Bitmap image, GetThumbnail() Method should return a Image* which points to Bitmap object in fact. But After tring it , I found it points to Image object...