I need to create a QImage
or something that can be drawn onto a screen from a geotiff image. Unfortunately QT's built-in TIFF support chokes on the geotiff structures ... so to achieve this I have used the following code (which is more or less a copy paste from the gdal "tutorial" page ( https://gdal.org/gdal_tutorial.html ) except the image creation part ):
GDALRasterBand *poBand;
int nBlockXSize, nBlockYSize;
int bGotMin, bGotMax;
double adfMinMax[2];
poBand = poDataset->GetRasterBand( 1 );
poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
adfMinMax[0] = poBand->GetMinimum( &bGotMin );
adfMinMax[1] = poBand->GetMaximum( &bGotMax );
if( ! (bGotMin && bGotMax) )
GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
float *pafScanline;
int nXSize = poBand->GetXSize();
int nYSize = poBand->GetYSize();
pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize * nYSize);
poBand->RasterIO( GF_Read, 0, 0, nXSize, nYSize,
pafScanline, nXSize, nYSize, GDT_Float32, 0, 0 );
QImage* image = new QImage((unsigned char*)pafScanline,
nXSize, nYSize,
QImage::Format_RGB32);
image->save("blaa.jpg");
Now, the image I try to load is on the left side and the one that gets displayed (and saved by Qt) is on the right side.
Question : how to create a properly coloured image from the tiff data given that I get in floats, and I have no idea how to create a QImage
data from a bunch of floats.
Your input GeoTIFF may not have a single floating point band, but rather 3 (or 4) 8 bit bands.
Bands in GeoTIFF are basically the image channels. Unlike other image formats, these channels can also have floating point values.
You can have a look at the GDAL documentation here to know more about the allowed formats.
So it is likely (although I can't be 100% sure without looking at it) that your file is just an RGBA GeoTIFF, and hence, has 4 UNIT8 bands.
Therefore, your call to RasterIO is completely wrong. You should iterate over the 4 bands and copy the with RasterIO to the QImage memory buffer, respecting the bands order.
Something like:
int nBands = poDataset->GetRasterCount();
for(int b=0; b < nBands; b++)
{
GDALRasterBand *band = poDataset->GetRasterBand(b);
if(band != nullptr)
{
CPLErr error = band->RasterIO(GF_Write, 0, 0, image.width(), image.height(), image.bits() + b, image.width(), image.height(), GDT_Byte, nBands, 0);
if(error != CE_None)
{
// REPORT ERROR
}
}
}
Please note that the code above is missing all the required checks (ensuring band type is Byte, etc), and depending on your file the band order may vary (BGRA, RGBA, ecc).
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.