【问题标题】:Convert GDI Plus Bitmap to QPixmap将 GDI Plus 位图转换为 QPixmap
【发布时间】:2017-03-22 16:52:55
【问题描述】:

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

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

【问题讨论】:

    标签: c++ qt gdi+ qimage qpixmap


    【解决方案1】:

    我假设您手中有“位图”对象。 另外我假设您的开发环境同时支持“Windows 编程”和“Qt”。

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

    步骤:

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

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

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

    【讨论】:

      【解决方案2】:

      我不需要访问像素数据

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

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

      【讨论】:

        【解决方案3】:

        我有一种方法可以翻转红色和蓝色字节,然后使用以下代码将其从 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;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-03-12
          • 1970-01-01
          • 1970-01-01
          • 2013-05-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多