【问题标题】:How to Convert GDI+'s Image* into Bitmap*如何将 GDI+ 的 Image* 转换为 Bitmap*
【发布时间】:2010-11-12 21:33:10
【问题描述】:

我正在用 c++、gdi+ 编写代码。

我使用 Image 的 GetThumbnail() 方法来获取缩略图。 但是,我需要将其转换为 HBITMAP。 我知道下面的代码可以获取GetHBITMAP:

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

但是如何快速将 Image* 转换为 Bitmap*? 非常感谢!

其实,现在我得用下面的方法:

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

我真的不知道他们为什么不提供 Image* -> Bitmap* 方法。但是让 GetThumbnail() API 返回一个 Image 对象....

【问题讨论】:

  • 你这样做的方式很好。它通常不能“快速”转换的原因是因为Image 根本不一定是位图 - 它可以是矢量图像(尽管我知道 GDI+ 支持的唯一矢量格式是 WMF/电磁场)。我想在这种情况下,GetThumbnail 也会生成矢量图。

标签: c++ image gdi+ bitmap


【解决方案1】:
Image* img = ???;
Bitmap* bitmap = new Bitmap(img);

编辑: 我正在查看 GDI+ 的 .NET 参考,但这里是 .NET 如何实现该构造函数的。

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

所有这些功能都在 C++ 版本的 GDI+ 中可用

【讨论】:

  • 我没有看到任何接受 Image*Bitmap 构造函数。
  • 我也是~~,也许在.NET中它可以工作,但是c++不提供这个构造函数
【解决方案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 将是 nullptr),那么您可以尝试更通用的解决方案。

例如,使用Save 方法将Image 保存到COM IStream,然后使用Bitmap::FromStream 从该流中创建Bitmap

可以使用CreateStreamOnHGlobal WinAPI 函数创建一个简单的COM IStream。然而,这并不高效,尤其是对于较大的流,但要测试它的想法。

还可以通过阅读ImageBitmap 文档推断出其他类似的解决方案。

遗憾的是,我还没有自己尝试过(Image 不是 Bitmap)所以我不完全确定。

【讨论】:

  • 实际上,问题中的代码是从通用图像中获取位图的绝佳方法。
  • 我的回答给出了潜在的最佳解决方案,因为 dynamic_cast 的成本很小(与绘制/复制图像相比)并且在大多数情况下我认为它会成功。如果不是,那么我的版本或有问题的代码(在我的回答之后添加)都是一种方法。问题中的代码似乎更简单,更安全。但是我不确定它将如何处理透明度。此外,如果可能的话,重构 getThumbnail 以返回 Bitmap* 可能会很有用,因为它似乎不太可能产生例如矢量图形。
  • 我同意对于位图图像,GetThumbnail() 方法应该返回一个实际上指向位图对象的 Image*。但是经过tring之后,我发现它指向Image对象...
【解决方案3】:

据我所知,您只需创建一个位图并将图像绘制到其中:

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

【讨论】:

    猜你喜欢
    • 2010-09-26
    • 2011-12-24
    • 2010-10-28
    • 2013-02-23
    • 2015-01-05
    • 2012-06-09
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    相关资源
    最近更新 更多