1

I have a GeoTIFF file which displays the following information when running gdalinfo:

Band 1 Block=10012x1 Type=Float32, ColorInterp=Gray
  Description = Layer_1
  Min=1638.991 Max=2577.040
  Minimum=1638.991, Maximum=2577.040, Mean=2063.003, StdDev=185.546
  NoData Value=-3.4028234663852886e+038
  Metadata:
    LAYER_TYPE=athematic
    STATISTICS_COVARIANCES=34427.3350382379
    STATISTICS_MAXIMUM=2577.0400390625
    STATISTICS_MEAN=2063.0031636173
    STATISTICS_MEDIAN=0
    STATISTICS_MINIMUM=1638.9908447266
    STATISTICS_MODE=0
    STATISTICS_SKIPFACTORX=1
    STATISTICS_SKIPFACTORY=1
    STATISTICS_STDDEV=185.54604560119

Based on this information, I understand that the minimum and maximum grayscale values are 1638.991 and 2577.040 respectively.

What I want to do is convert this GeoTIFF to a 16-bit PNG image which shows ~938 (2577-1638) different shades of gray. I'm attempting to achieve this with the following gdal_translate command:

"c:\Program Files\GDAL\gdal_translate.exe" -outsize 4096 4096 -of PNG -ot UInt16 -scale 1638.991 2577.040 0 65535 "GDAL_IMG_2_GeoTIFF.tif" "GDAL_IMG_2_GeoTIFF.png"

My understanding here is that -ot UInt16 allows me to create a 16-bit image and -scale 1638.991 2577.040 0 65535 re-maps the geoTIFF grayscale range to the full 16-bit range (0 - 65535).

This command does indeed produce what appears to be a 16-bit image however when viewing the image properties in irfanView, the Number of unique colors is showing as 256.

Full bit-depth info:

irfanView output

Is there any step that I have missed here for creating 16-bit PNG's which make use of > 256 shades of gray or perhaps a better method?

4

3 Answers 3

2

I took bugmenot123's advice and trusted the GDAL output rather than IrfanView which seems to have issues accurately showing bit depth. I double checked the PNG images in QGIS which showed the correct 16-bit range.

2

Perhaps you should update your gdal. Using version 2.4.0 I can generate 16bit PNGs with this command:

$ gdal_translate -of PNG -ot UInt16 -scale 32.53501 767.4913 0 65535 goes16.abi-2019.0902.1510-C01_1km.tif k.png

$ pngcheck k.png
OK: k.png (2574x1591, 16-bit grayscale, non-interlaced, 35.0%).

The original data is Float32.

0

Please have a look at convert.py module here


import os
from osgeo import gdal

def geotiff_to_png(input_path, output_path=None, return_object=False):
    """
    Converts a GeoTIFF file to a PNG file or object. Specific to Skysatimages with 4 bands (blue, green, red, nir).

    Args:
        input_path (str): The file path of the input GeoTIFF file.
        output_path (str, optional): The file path of the output PNG file. If not provided, PNG object is returned. Defaults to None.
        return_object (bool, optional): Whether to return the PNG data as an object. If True, the output_path parameter will be ignored. Defaults to False.

    Returns:
        numpy.ndarray or None: If output_path is not provided and return_object is True, returns a 3D numpy array representing the PNG image. Otherwise, returns None.

    """
    # Open input file
    dataset = gdal.Open(input_path)
    output_types = [gdal.GDT_Byte, gdal.GDT_UInt16, gdal.GDT_Float32]
    
    # Define output format and options
    options = gdal.TranslateOptions(format='PNG', bandList=[3,2,1], creationOptions=['WORLDFILE=YES'], outputType=output_types[0])
    
    # Translate to PNG
    if output_path is not None:
        gdal.Translate(output_path, dataset, options=options)
        print(f'Successfully saved PNG file to {output_path}')
    
    # Return PNG object
    if return_object:
        mem_driver = gdal.GetDriverByName('MEM')
        mem_dataset = mem_driver.CreateCopy('', dataset, 0)
        png_data = mem_dataset.ReadAsArray()
        return png_data
1
  • 1
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    May 1, 2023 at 4:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.