【问题标题】:QImage: Read 16-bit grayscale TIFF (Qt, C++)QImage:读取 16 位灰度 TIFF(Qt、C++)
【发布时间】:2015-08-17 07:04:18
【问题描述】:

我想使用 C++、Qt 和 libtiff 读取 16 位灰度图像。我创建了从 tiff 读取数据到 QImage 的 readTiff 函数(如下)。但是,有一个问题是QImage 5.5 doesn't support 16-bit grayscale。如果我使用 RGB16,我只会得到噪点。

如何破解 QImage 以支持 Format_Grayscale16 或将数据转换为 Format_Grayscale8 ?

/**
 * @brief Reads TIFF image
 * @param path
 * @return QImage
 */
QImage EdsImporter::readTiff(const QString &path) const {

  // Loads tiff file
  TIFF* tiff = TIFFOpen(path.toStdString().c_str(), "r");
  if (!tiff) {
    QString msg = "Failed to open TIFF: '" + path + "'";
    throw new Exception(NULL, msg, this, __FUNCTION__, __LINE__);
  }

  // Temporary variables
  uint32 width, height;
  tsize_t scanlength;

  // Read dimensions of image
  if (TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width) != 1) {
    QString msg = "Failed to read width of TIFF: '" + path + "'";
    throw new Exception(NULL, msg, this, __FUNCTION__, __LINE__);
  }
  if (TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height) != 1) {
    QString msg = "Failed to read height of TIFF: '" + path + "'";
    throw new Exception(NULL, msg, this, __FUNCTION__, __LINE__);
  }

  // Number of bytes in a decoded scanline
  scanlength = TIFFScanlineSize(tiff);

  QImage image(width, height, QImage::Format_RGB16);

  // TEMPORARY: Save to PNG for preview
  image.save("tiff/" + StringUtils::random() + ".png", "PNG");

  if (image.isNull() || scanlength != image.bytesPerLine()) {
    TIFFClose(tiff);
    QString msg = "Failed to create QImage from TIFF: '" + path + "'";
    throw new Exception(NULL, msg, this, __FUNCTION__, __LINE__);
  }

  // Read image data
  for (uint32 y = 0; y < height; y++) {
    TIFFReadScanline(tiff, image.scanLine(y), y);
  }
  TIFFClose(tiff);
  return image;
}

【问题讨论】:

  • 你试过thisthis吗?
  • 我看到了这两个问题。第一个是关于 C++ 的;然而,正确的答案对我来说似乎并不简单。
  • 即使第二个是python,它背后的逻辑也应该很容易翻译成c++

标签: c++ qt tiff qimage libtiff


【解决方案1】:

试试这个应该可以(我没有测试,只是从头开始写)

QImage convertGray16TifToQImage(TIFF *tif) {
    // Temporary variables
    uint32 width, height;

    // Read dimensions of image
    if (TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width) != 1) {
        QString msg = "Failed to read width of TIFF: '" + path + "'";
        throw new Exception(NULL, msg, this, __FUNCTION__, __LINE__);
    }
    if (TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height) != 1) {
        QString msg = "Failed to read height of TIFF: '" + path + "'";
        throw new Exception(NULL, msg, this, __FUNCTION__, __LINE__);
    }
    QImage result(width, height, QImage::Format_Grayscale8);

    QVarLengthArray<quint16, 1024> src(width);
    for (uint32 y=0; y<height; ++y) {
         TIFFReadScanline(tiff, src.data(), y, 0);
         quint8 *dst = (quint8 *)result.scanLine(y);
         for (uint32 x=0; x<width; ++x) {
              dst[x] = src[x]>>8; // here you have a room for tweaking color range usage
         }
    }
    return result;
}

【讨论】:

  • 这是可行的解决方案..清除 Qt 代码...谢谢 Marek
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 2013-03-18
  • 1970-01-01
  • 2014-08-09
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多