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