When converting to PNG I'd like to convert the height of the GeoTIFF (which is a float) to UINT16, but also setting the maximum range to 5500, by clamping any values smaller or larger to min or max value. I'd also like to set it in such away that if I translate another file it has the exact same scaling factor.

For example

  • range [130, 160] -> [630, 660]
  • range [5, 200] -> [505, 700]
  • range [-100, 6700] -> [400, 5500]

I have the following code, however, the scale doesn't seem to be consistent when I translate two adjacent GeoTIFFs to PNGs. There is discontinuity at the seems, due to (what I expect is) the scale for the two images being slightly different.

from osgeo import gdal, gdalconst

UINT_16_MAX_VALUE = 65535

def translate(output_file_name, dataset, top_left, bottom_right):

    # We need to change the scale of topological information as it is in Mean Sea Level. 
    opt = gdal.TranslateOptions(
        # do we want nodata to be zero or smallest number or "unset"
        noData = None,
        # This assumes each pixels is 1 meter.
        projWin= [top_left[0], top_left[1], bottom_right[0], bottom_right[1]],
        # dem.tif comes in float values which are in meters. 
        # Assuming the original scale is a bit below sea level to a bit above. 
        scaleParams=[(-500,5000,UINT_16_MIN_VALUE, 5500)]

    return gdal.Translate(output_file_name, dataset, options=opt)
  • Do you wish that 5500 is the absolute maximum of the output? Gdal_translate and -scale do not guarantee that. You command does convert value 5000 into 5500, but if your source data has values above 5000 they will be converted linearly into something greater than 5500. gdal.org/programs/…. However, the scaling is linear and with fixed scale parameters the same input value should always yield the same scaled value for any input image. Please provide test data if you observe something else.
    – user30184
    Dec 7, 2022 at 17:01
  • Okay I'll figure out a different way to clamp the highs and lows. However, when I take a single DEM, and tile it into 4 smaller DEMs with the above function, the greyscale on the two sides of the seam are noticeably different (when viewed in QGIS). However, when I look at the original file they are the same. I've either misunderstood or it should be impossible.
    – Joe
    Dec 7, 2022 at 19:38
  • Provide test data. Also make sure that you don't have any contrast enhancement on or alternatively stretch to fixed min/max in QGIS layer-symbology.
    – user30184
    Dec 7, 2022 at 19:41
  • Is there a standard practice for providing test data? or should i just load the images to google drive or something similar.
    – Joe
    Dec 7, 2022 at 19:42
  • 1
    Doh! The stretch to min max is what was causing my coloring issue, giving them all the same window solves the coloring problem. The other issue is caused by the lack of clamping. I really appreciate you taking the time. I've uploaded the files in case you are curious.
    – Joe
    Dec 7, 2022 at 19:49

1 Answer 1


Short Answer: I was setting the scale correctly, and I was just interpreting the output incorrectly.

Long Answer: There were two things that were causing me to think there was an issue with scaling. First, was in how I was viewing the data and second, was how I assumed values outside the scale were treated.

  1. In QGIS, the software I was using to view the data, by default the viewer "stretches" the color scale to expose more details in your image. So if you are importing two different images with the same scale, the same height value might (and probably will) have a different color. What I did to "fix this issue" was in QGIS layer-symbology to manually set the min and max value across the DEM files to be the same. After doing this it was clear they were all on the same scale.

  2. My other issue, which caused me to think there was an issue in the first place, is that values that are below the min and above the max are not clamped. I had incorrectly assumed that if you set the source scale 0-100 that any value above would be clamped to 100, then converted to the new scale. This is not the case, as @user30184 pointed out, the scale you set is linearly applied even for values outside the min and max of the output scale you provide.

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.