3

I have some Python GDAL code I am using to convert a GeoTIFF file to PNG. The code uses the gdal.Translate() function which generates a new file each time I run it. However, I was wondering if there is a way to get the Python gdal.Translate() function to return a python object instead of writing a file? Ideally I would like to write to a numpy array or something, but any kind of internal object would be fine.

Here is some sample code I am using:

from osgeo import gdal

scale = '-scale min_val max_val'
options_list = [
    '-ot Byte',
    '-of JPEG',
    scale
] 
options_string = " ".join(options_list)

gdal.Translate('test.jpg',
               'test.tif',
               options=options_string)

I looked over the documentation and source code to figure out how gdal.Translate() worked, but could not get past the TranslateInternal() function. I could not find a link through the source code past that.

1
  • There is a memory driver which may help gdal.org/frmt_mem.html I'm not sure how you could leverage the pointer in python but it works great in C++ (until you create a raster larger than your available memory). TranslateInternal() would be calling a C external link, you could find it in the source code if you understand ANSI C/C++. It might be best to write to a file in your os.environ.get('temp') then gdal.Open the temp raster. Mar 19, 2019 at 23:27

1 Answer 1

6

gdal.Translate does return an object, it returns a gdal.Dataset object.

from osgeo import gdal
in_ds = gdal.OpenEx('path/to/input.tif')
print(in_ds)

<osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0x00000000037BE930> >

out_ds = gdal.Translate('path/to/output.tif', in_ds)
print(out_ds )

<osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0x00000000037BE990> >

It has to write the translated output somewhere...

If you don't want to write to disk, write to memory (don't bother with the MEM driver), use the "VSIMEM" virtual filesystem to write a GeoTIFF to memory:

out_ds = gdal.Translate('/vsimem/in_memory_output.tif', in_ds)

You can then read it into a numpy array if you want.

out_arr = out_ds.ReadAsArray()
5
  • Oh this is great. Yeah, I will give this a try. This will make stuff a lot easier. Just to anticipate my next question, can I convert a Dataset object to a numpy array using the ds.GetRasterBand(1).ReadAsArray() function? Is that what you were thinking or am I thinking in the wrong direction.
    – krishnab
    Mar 20, 2019 at 0:20
  • Oh thank you so much. I was trying to figure this out since yesterday. Haha, like if I had energy left I would thank you more :). Yeah, so that will load all the bands into an array. I was trying to figure out if I needed to manually stack each band into an RGB array or shift from a raster ordering of the data to an image ordering, etc. But this totally answers my question.
    – krishnab
    Mar 20, 2019 at 0:34
  • Yep, that is what I figured. I can use the rasterio.plot.reshape_as_image() function to then reorder it into row, column, bands order :).
    – krishnab
    Mar 20, 2019 at 0:39
  • Ahh, good tip. No I am not writing out to a raster again. I am taking the TIFF data and encoding it to a TFRecords format for some machine learning in Tensorflow. Kinda a long story but trying to be systematic about it. So I need to take the TIFF data, convert it to 8bit format, encode it as a string and write it to TFRecords. But then I need to decode the data from string in Tensorflow and validate the data went in properly. So I need to be able to check the decoded data and that is why I was using a PNG or JPEG format since they are easy to plot.
    – krishnab
    Mar 20, 2019 at 0:50
  • Haha, I know it is not the easiest and that conversion from 16bit TIFF to 8bit loses information. But just need to get the basic prototype working and then can make the necessary fixes to do it right.
    – krishnab
    Mar 20, 2019 at 0:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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