简体   繁体   中英

QImage: Read 16-bit grayscale TIFF (Qt, C++)

I want to read 16-bit grayscale images using C++, Qt and libtiff. I've created the readTiff function (below) that reads data from tiff to QImage. However, there is a problem that QImage 5.5 doesn't support 16-bit grayscale . And if I use RGB16, I'll get only noise.

How can I hack QImage to support Format_Grayscale16 or convert data to 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;
}

Try this it should work (I didn't test it, just write from scratch)

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM