I have a GeoTiff that acquired through processing Mars Hirise stereo images with ISIS3 and ASP. I want to convert it to a 16bit greyscale tiff, png or bmp file to use as a heightmap in a game engine, unreal engine 4. I tried converting it with gdal_translalte, first to 16 bit .raw but turns out photoshop can't open it in 16 bit only in 8bit, I get a message saying that the size is to big for the file in 16 bit, something that seems to have to do with the file size in byte, the two channels and the image size I try to import. Then I tried converting it to tiff and png, also with gdal_translate but both images are just black when I open them. I tried opening my GeoTiff with BelnderGIS but it is just a flat plane. I opened the Geotiff in QGIS and then I see that it does have information and is not just flat and black. I made a smaller cropped version of the DEM and opened it in MicroDEM which works but when I try to open the original file it says that it is too big.

Does anybody know how I could do this, with gdal, qgis or something else? I'm very new to using both gdal and and qgis, I just followed examples from others but there might be a way to do it so it works for me in the end.

2 Answers 2


I think the problem could be with the range of values in your original image. You can use the -scale parameter in gdal_translate to get images within the range of an 8 bit image.

For example

gdal_translate -of PNG -ot Byte -scale in_tiff.tif out_png_scaled.png

This will automatically set the input minimum and maximum values used to scale, if these don't work you can specify a minimum and maximum value after -scale.

If you need to make the image smaller you can also resize with gdal_translate using -outsize. For example, -outsize 50% 50% will resize to 50 % of the original.

  • Yes it seems to be something with the range, when I open it in sagaGIS both min and max is around -5600. I tried your example and it worked but what I want is 16 bit so I tried putting in UInt16 for Unsigned 16bit but then the image just comes out white, do you know what the right input would be to get a 16bit Tiff or PNG?
    – Stina_F
    Aug 16, 2016 at 18:48
  • You can pass in input minimum maximum and output minimum maximum to the scale parameter to get a 16 bit output. If the minimum and maximum are both -5600 that would mean all the pixels have the same value (-5600) so the scale parameter won't help.
    – danclewley
    Aug 16, 2016 at 19:51
  • 2
    Thank you that worked perfectly! My min and max values are -5660.574 and -5618.043 so I did gdal_translate -of PNG -ot Float16 -scale -5660.574 -5618.043 0 65535 input.tif output.png
    – Stina_F
    Aug 17, 2016 at 9:12
  • Well, UInt16 was what I meant in the code above instead of Float16 though both works.
    – Stina_F
    Aug 18, 2016 at 13:44
  • I have an other question concerning this, does this stretch the values over the whole range or does it just move them up? What I want is to just move them up.
    – Stina_F
    Sep 1, 2016 at 17:00

For that purpose I use Python script. It can split big GeoTIFF image for smaller tiles with overlapping. Outputting height map is ready to use in unreal engine 4 in single landscape or levels streaming (world composition). Here you can find a detailed explanation

import os
import gdal
import subprocess

source_path = 'C:/Users/unreal4/Downloads/AP_08049_FBD_F0980_RT1/heightmap.tif'
tiles_folder = 'C:/Users/unreal4/Downloads/AP_08049_FBD_F0980_RT1/tiles/'

tile_size_x = 2017
tile_size_y = 2017

tile_prefix = "tile"
tile_x = 0
tile_y = 0

ds = gdal.Open(source_path)
band = ds.GetRasterBand(1)
xsize = band.XSize - 1
ysize = band.YSize - 1

min_height = 384.5
max_height = 1105.8

for i in range(0, xsize, tile_size_x - 1):
    for j in range(0, ysize, tile_size_y - 1):
        format = "-ot UInt16 -of PNG -scale " + str(min_height) +  " " + str(max_height) + " 0 65535"
        cutting_frame = "-srcwin " + str(i) + " " + str(j) + " " + str(tile_size_x) + " " + str(tile_size_y)
        output_path = tiles_folder + tile_prefix + "_x" + str(tile_x) + "_y" + str(tile_y) + ".png"
        full_command = "gdal_translate " + format + " " + cutting_frame + " " + source_path + " " + output_path
        # version with subprocess module
        # args = ['gdal_translate', '-ot', 'UInt16', '-of', 'PNG', '-scale', str(min_height), str(max_height), '0', '65535', '-srcwin', str(i), str(j), str(tile_size_x), str(tile_size_y), source_path , output_path]
        # subprocess.check_call(args)
        tile_y = tile_y + 1
    tile_x = tile_x + 1
    tile_y = 0

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.