将 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;
}
我有一个 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;
}