简体   繁体   中英

How to create a QImage from GeoTIFF data (or just interpret it correctly)

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.

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