5

I need to convert a Float32 tiff image to 8bit format in order to display the image in a web page. In order to do that I need a jpg image but this conversion is not correctly done with GDAL because the image is Float32 type. So I want to convert to 8bit type with Python.

Can you help me?

I've tried something like this:

gdal.AllRegister()  
src = gdal.Open(str(input_file)) 
src_data = src.ReadAsArray()
cols = src.RasterXSize
rows = scr.RasterYSize
driver = gdal.GetDriverByName("GTiff")
dst = driver.Create(str(output_file), cols, rows, 1, gdal.GDT_Byte)
dst.GetRasterBand(1).WriteArray(src_data)
#dst = drv.CreateCopy(output_file, src, 0, saveOptions)

I try with Create() and CreateCopy() but I always get a black image.

7
  • Do you definitely want to do it with Python and not with a gdal_translate command?
    – user30184
    Apr 22, 2015 at 15:56
  • I need to solve it inside an application (a script) so I prefer with Python. It is possible? Apr 22, 2015 at 15:57
  • For sure it is possible but I am not the one who knows how. I would first study the histogram of the original and the all black image you have with gdalinfo -stats. 32 bit images often have data only on the lower end of the scale which make them look like totally black if they are viewed without stretching the histogram. Then you may need to find an equivalent to -scale option of gdal_translate gdal.org/gdal_translate.html for Python.
    – user30184
    Apr 22, 2015 at 16:03
  • I try what you said and the black image as the same information about the original image. But it appears in black. How do I correct that? Apr 23, 2015 at 14:44
  • Much easier than to explain is to show an example with real data. Do you have some test data to be used as input?
    – user30184
    Apr 23, 2015 at 14:52

2 Answers 2

6

You can do that directly in QGIS with Raster -> Conversion -> Translate (Convert Format). To test it, I used a Float64 (Sixty four bit floating point) raster (named test) loaded in the Map View of QGIS. To convert it to Byte (8 bit type), I named it first at the "output file space" as test_byte.tif and afterward, I click in the icon pencil of "Translate Window" to modify gdal_translate command to:

gdal_translate -ot Byte -of GTiff /home/zeito/proyectosR/test.tif /home/zeito/proyectosR/test_byte.tif

as in the following image:

enter image description here

After click in OK, it can be observed at the layer properties of test_byte.tif that this raster is "Eight bit unsigned integer":

enter image description here

Editing Note:

This code works (to change the data type) in my bash console (in Windows is necessary to use IDLE Python GUI):

from osgeo import gdal, osr

dataset = gdal.Open('tiznados_canoa.tif')

geotransform = dataset.GetGeoTransform()

prj=dataset.GetProjection()

values = dataset.ReadAsArray()

band = dataset.GetRasterBand(1)

#Get minimum and maximum values of raster
min = band.GetMinimum()
max = band.GetMaximum()

#if not exist minimum and maximum values
if min is None or max is None:
    (min,max) = band.ComputeRasterMinMax(1)

print "Min=%.3f, Max=%.3f" % (min,max) #print minimum and maximum values

# Set output file
output_file = "out.tif"

# Create new GTiff (Byte type)
driver = gdal.GetDriverByName("GTiff")
dst_ds = driver.Create(output_file, band.XSize, band.YSize, 1, gdal.GDT_Byte)

print "rows = ", band.YSize, "columns = ", band.XSize

print "Executing..."

for i in range(band.YSize):
    for j in range(band.XSize):

        values[i][j]

dst_ds.GetRasterBand(1).WriteArray( values )

# top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution
dst_ds.SetGeoTransform( [ geotransform[0], geotransform[1], 0, geotransform[3], 0, geotransform[5] ] )

# set projection of new raster
dst_ds.SetProjection( prj )

dataset = None
5
  • Yes, I know how to do it in QGIS but I want python code to insert in a script. That's my dificulty. Apr 23, 2015 at 16:12
  • As you said "I need to convert a Float32 tiff image to 8 bit format in order to display the image in a web page", for this requirement you don't need Python and the reason of my answer. However, it's not difficult to do that.
    – xunilk
    Apr 23, 2015 at 16:20
  • Yes, but the process is inside an application. So I need to automatize the process. I try to use the command gdal_translate in python script through os.system and subprocess.call but without success. Apr 23, 2015 at 16:56
  • You have my code with GDAL (See my Editing Note).
    – xunilk
    Apr 23, 2015 at 19:07
  • By the way, subprocess doesn't work in my system after actualization of my QGIS to 2.8 version. For this reason I used GDAL library in Python.
    – xunilk
    Apr 23, 2015 at 19:25
4

The most easy way to do this in a script is to use the subprocess module and gdal_translate

import subprocess

image_in = "path_input_image"
image_out = "path_output_image.tif"
subprocess.call(["gdal_translate.exe","-co", "TILED=YES", "-co", "COMPRESS=LZW" "-ot", "Byte", "-scale", image_in, image_out ])

f you are in Linux, you don't need the ".exe" after gdal_translate, and if gdal is not installed, you might need to provide the full path to the application

alternatively, this can be done with OTBApplication

#!/usr/bin/python

# Import the otb applications package
import otbApplication

image_in = "path_input_image"
image_out = "path_output_image.tif"

# The following line creates an instance of the Rescale application
Rescale = otbApplication.Registry.CreateApplication("Rescale")

# The following lines set all the application parameters:
Rescale.SetParameterString("in",image_in )

Rescale.SetParameterString("out",image_out )
Rescale.SetParameterOutputImagePixelType("out", ImagePixelType_uint8)

Rescale.SetParameterFloat("outmin", 0)

Rescale.SetParameterFloat("outmax", 255)

# The following line execute the application
Rescale.ExecuteAndWriteOutput()
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.