2009-07-22 5 views
3

Я пишу код в C++, gdi +.Как преобразовать изображение GDI + * в растровое изображение *

Я использую метод GetThumbnail() Image, чтобы получить уменьшенное изображение. Однако мне нужно преобразовать его в HBITMAP. Я знаю, следующий код можно получить GetHBITMAP:

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

Но как я могу преобразовать изображение * в растровое изображение * быстро? Большое спасибо!

На самом деле, теперь я должен использовать следующий метод:

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

Я действительно не знаю, почему они не обеспечивают изображение * -> Bitmap * метод. но пусть GetThumbnail() API возвращает изображение объекта ....

+4

, как вы делаете это хорошо. Причина, по которой он не может быть преобразован «быстро» в общем, заключается в том, что «Image» не обязательно является растровым изображением вообще - это может быть векторное изображение (хотя единственный векторный формат, который мне известен, поддерживается GDI +, - это WMF/EMF). Я бы предположил, что в этом случае «GetThumbnail» также создаст векторное изображение. –

+0

Большое спасибо! Ваш комментарий звучит разумно! – user25749

ответ

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

Edit: Я смотрел на the.NET ссылки на GDI +, но вот как .NET реализует этот конструктор.

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

Все эти функции имеющиеся в версии C++ в GDI +

+1

Я не вижу конструкторов для 'Bitmap', которые принимают' Image * '. –

+1

меня тоже ~~, Может быть, в.NET это работает, но C++ не предоставляют этот конструктор – user25749

2

Во-первых, вы можете попробовать dynamic_cast как и во многих случаях (если не большинство - по крайней мере, в моем случае использования) Image действительно является Bitmap. Так

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. 

Однако, если как-то это не так (bitmap будет NULL), то вы можете попробовать более общее решение.

Например сохранить Image в COMIStream используя Save метод, а затем использовать Bitmap::FromStream для создания Bitmap из этого потока.

Простой COMIStream может быть создан с помощью функцииCreateStreamOnHGlobalWinAPI. Однако это неэффективно, особенно для больших потоков, но для проверки идеи, которую это будет делать.

Существуют и другие аналогичные решения, которые могут быть получены из документации Image и Bitmap.

К сожалению, я не пробовал это самостоятельно (с Image, который не является Bitmap), поэтому я не совсем уверен.

+0

Кажется, метод getThumbnail возвращает Image * Object ... – user25749

+1

Собственно, код в вопросе - отличный способ получить Bitmap из общего изображения. –

+1

Мой ответ дает потенциально оптимальное решение, так как стоимость dynamic_cast небольшая (по сравнению с рисованием/копированием изображения), и в большинстве случаев я думаю, что это будет успешным. Если нет, то моя способ или код (добавленный после моего ответа) - это способ сделать. Код из вопроса кажется более простым и безопасным. Однако я не уверен, как прозрачность будет обрабатываться им. Также, если это возможно, может оказаться полезным рефакторинг getThumbnail для возврата Bitmap *, поскольку он не кажется вероятным, что он создает, например, векторную графику. –

1

Насколько я могу сказать, что вам нужно просто создать растровое изображение и раскрасит изображение в нем:

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; 
} 
Смежные вопросы