将 GDI Plus 位图转换为 QPixmap

Convert GDI Plus Bitmap to QPixmap

我有一个 GdiPlus::Bitmap 对象,我需要构建一个将其转换为 QPixmap 的函数。我正在使用 Qt 5.8.0,性能是我关心的问题。我在网上找不到任何相关信息,甚至无法在 QImages 中搜索 GDI+ 图像。我不需要访问像素数据,所以我所要做的就是将 GDI+ 位图转换成可以在 QWidget 中显示的内容。

到目前为止我发现的最有前途的解决方案是在 QtWin 中使用 fromHBitMap():http://doc.qt.io/qt-5/qtwin.html#fromHBITMAP,但我没有所需的 knowledge/experience 来理解句柄到位图。

我假设你手上有 "Bitmap" 个对象。 另外我假设你的开发环境同时支持 "Windows programming" 和 "Qt".

基于以上假设,您可以从"Bitmap"中获取HICON并将其传递给“QPixmap QtWin::fromHICON(HICON icon)”。

步骤:

首先你必须包含“Gdiplus.h”。 还包括“QtWin”。

HICON hIcon;
Status st = <<Your Bitmap Object>>.GetHICON(&hIcon);
QPixmap pixM = QtWin::fromHICON(hIcon);

试试这个。 上面的代码未经测试。 它给出了一个想法。

I don't NEED to access pixel data

你不知道,但 Qt 肯定有。 Qt 不使用 GDI 来呈现小部件 - 相反,它使用在 QImage 上运行的光栅后端。在引擎盖下,QPixmap 只是 QImage 的包装,并且在两者之间进行转换很便宜,因为它不复制任何图像数据。

因此,无论您选择何种路线,都会在某个时候涉及 QImage,即使它的形式是 QPixmap

我有一种方法可以翻转红色和蓝色字节,然后使用以下代码将其从 Gdiplus::Bitmap 转换为 QPixmap:

QPixmap getAsQPixmap(Gdiplus::Bitmap bitmap)
{
   // One of my functions to flip blue and red bytes of the image
   _flipBlueWithRed();

   // m_pBytes is a pointer to an unsigned char that marks the start of the image
   // It was retrieved from locking the Gdiplus::Bitmap
   auto result = QPixmap::fromImage(QImage(m_pBytes, getWidth(), getHeight(), QImage::Format_RGB888));

   // Restore data back to original state
   _flipBlueWithRed();

   return result;
}

但是,此方法很慢,执行时间长达 60 毫秒。所以我的新方法是将 Gdiplus::Bitmap 保存到文件,并使用该文件的路径从 QPixmap 的构造函数中读取。 这种方法要快得多,大约 5 毫秒。

QPixmap getAsQPixmap(GdiPlus::Bitmap bitmap)
{
    std::string path = "C:/path_to_img.....png";

    // One of my functions to unlock the Gdi+ bitmap
    _unlockGdiPlusBitmap();

    // Get Clsid
    CLSID pngClsid;
    getEncoderClsid(format_mime, &pngClsid);

    // Save bitmap
    // stringToWString() was a function that I wrote to convert a standard string to be a wide string
    bitmap->Save(stringToWString(path).c_str(), static_cast<const CLSID*>(&pngClsid));

    // Lock bitmap
    _lockGdiPlusBitmap();

    // Create the QPixmap
    QPixmap new_img(path);

    return new_img;
}