【问题标题】:Create a QImage from a BITMAPINFO and an uchar* data从 BITMAPINFO 和 uchar* 数据创建 QImage
【发布时间】:2021-05-31 07:12:43
【问题描述】:

我正在尝试加载作为BITMAPINFO*uchar 数组提供给我的图像。 文档声明它是标准的 Microsoft 设备无关位图 (DIB),具有 8 位像素和 256 项颜色表

我目前可以通过以下方式打开此图片:

BITMAPINFO* bmih = givenBITMAPINFO;
uchar* data = givenData;

QImage img = QImage(data, bmih->biWidth, bmih->biHeight, QImage::Format_Grayscale8);

但我有两个问题:

  1. 当文档声明一个 8 位像素和一个 256 项颜色表时,图像位于 QImage::Format_Grayscale8

  2. 图像颠倒并镜像。这来自位图数据在 Win32 中的存储方式。

有人知道我如何正确加载此图像吗?

【问题讨论】:

  • 8 位 DIB 的颜色信息存储在调色板中。该调色板遵循标准位图文件中的BITMAPINFOHEADER。除非您的指针指向BITMAPINFOHEADER,然后是调色板,否则您无法协调颜色信息。
  • 好的,我想我可以从BITMAPINFO 获取颜色表。但是图像是向后的,什么是最有效的加载方式?
  • 似乎没有任何QImage c'tors 能够翻转图像,因此您必须应用QImage::mirrored 作为第二步。另请注意,有QImage::setColorTable。结合QImage::Format_Indexed8 图像格式,您应该能够构建图像。
  • QImage::mirrored() 复杂度高还是应该使用其他库?
  • 如有疑问,请测量。垂直翻转图像不可避免地会导致复制内存中的所有像素数据。任何图像库都必须这样做。

标签: c++ qt winapi qimage bitmapdata


【解决方案1】:

通过将提供的标题转换为BITMAPINFO 而不是BITMAPINFOHEADER,我可以访问颜色表,然后应用转换来获得立体图像:

BITMAPINFO* bmi = givenHeader;
uchar* data = givenData;

QImage img = QImage(data, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, QImage::Format_Indexed8);

img.setColorCount(256);
for (int i=0; i<256; ++i){
    RGBQUAD* rgbBmi = bmi->bmiColors;
    img.setColor(i, qRgb(rgbBmi[i].rgbRed, rgbBmi[i].rgbGreen, rgbBmi[i].rgbBlue))
}

img = img.mirrored(false, true);

【讨论】:

  • 虽然这可以解决您的特定问题,但它不是一个通用的解决方案。该问题表明您拥有的只是BITMAPINFOHEADER*,此解决方案要求客户拥有完整的BITMAPINFO*
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
  • 2020-03-24
  • 2014-10-14
  • 2011-03-23
相关资源
最近更新 更多