2009-07-22 6 views
3

Je suis en train d'écrire du code en C++, gdi +. J'utilise la méthode GetThumbnail() d'Image pour obtenir une vignette. Cependant, j'ai besoin de le convertir en HBITMAP. Je sais que le code suivant peut se GetHBITMAP:Comment faire pour convertir l'image de * GDI + en bitmap *

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

Mais comment puis-je convertir l'image * dans Bitmap * rapide? Merci beaucoup!

En fait, maintenant je dois utiliser la méthode suivante:

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); 

Je ne sais vraiment pas pourquoi ils ne fournissent pas l'image * -> Méthode Bitmap *. mais laissez GetThumbnail() API retourne un objet image ....

+4

La façon dont vous faites cela est très bien. La raison pour laquelle il ne peut pas être converti "fast" en général est parce que 'Image' n'est pas nécessairement une bitmap - il peut s'agir d'une image vectorielle (bien que le seul format vectoriel que GDI + supporte soit WMF/EMF). J'imagine que dans ce cas, 'GetThumbnail' produirait aussi une image vectorielle. –

+0

Merci beaucoup! Votre commentaire semble raisonnable! – user25749

Répondre

3
Image* img = ???; 
Bitmap* bitmap = new Bitmap(img); 

Edit: Je regardais référence the.NET de GDI +, mais voici comment .NET implémente ce constructeur.

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

Toutes les fonctions sont disponible dans la version C++ de GDI +

+1

Je ne vois aucun constructeur pour 'Bitmap' qui accepte un' Image * '. –

+1

moi aussi ~~, Peut-être dans.NET cela fonctionne, mais C++ ne fournit pas ce constructeur – user25749

2

D'abord, vous pouvez essayer dynamic_cast comme dans de nombreux cas (sinon plus - au moins dans mes cas d'utilisation) Image est en effet un Bitmap. Alors

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. 

Toutefois, si elle est en quelque sorte pas (bitmap seront NULL) alors vous pouvez essayer une solution plus générale.

Par exemple enregistrer le Image à un COMIStream en utilisant la méthode Save puis utiliser Bitmap::FromStream pour créer Bitmap à partir de ce flux.

Un simple COMIStream pourrait être créée en utilisant l'CreateStreamOnHGlobalWinAPI fonction. Cependant, ce n'est pas efficace, surtout pour les plus grands flux, mais pour tester l'idée que cela va faire.

Il existe également d'autres solutions similaires qui peuvent être déduites de la lecture des documents Image et Bitmap. Malheureusement je ne l'ai pas essayé seul (avec Image qui n'est pas un Bitmap) donc je ne suis pas entièrement sûr.

+0

Il semble que getThumbnail Method renvoie un Image * Object ... – user25749

+1

En fait, le code dans la question est un excellent moyen d'obtenir un Bitmap sur une Image générique. –

+1

Ma réponse donne une solution potentiellement optimale puisque le coût de dynamic_cast est faible (comparé au dessin/copie de l'image) et dans la plupart des cas je pense que ça va réussir. Si ce n'est pas le cas, ma version ou le code en question (ajouté après ma réponse) est un moyen de le faire. Le code de la question semble plus simple et plus sûr. Cependant, je ne suis pas sûr de la façon dont la transparence sera traitée par elle. Aussi, si possible, il peut être utile de refactoriser getThumbnail pour renvoyer Bitmap * car il ne semble pas probable qu'il produise par exemple un graphique vectoriel. –

1

Pour autant que je peux vous dire doivent simplement créer une image bitmap et peindre l'image en elle:

Bitmap* GdiplusImageToBitmap(Image* img, Color bkgd = Color::Transparent) 
{ 
    Bitmap* bmp = nullptr; 
    try { 
     int wd = img->GetWidth(); 
     int hgt = img->GetHeight(); 
     auto format = img->GetPixelFormat(); 
     Bitmap* bmp = new Bitmap(wd, hgt, format); 
     auto g = std::unique_ptr<Graphics>(Graphics::FromImage(bmp)); 
     g->Clear(bkgd); 
     g->DrawImage(img, 0, 0, wd, hgt); 
    } catch(...) { 
     // this might happen if img->GetPixelFormat() is something exotic 
     // ... not sure 
    } 
    return bmp; 
} 
Questions connexes