[gdal-dev] More information to understand ColorTables in GeoTiffs

Robert Nix robert at urban4m.com
Sun Mar 10 09:43:54 PDT 2013


Maybe someone can just show me a working python example of how to create a color table in a tiff using gdal?

Here's what i've tried. It seems all the "Invalid value" errors are the closest to success.

c1 = c.SetColorEntry(1,"1,2")
TypeError: Invalid values in ColorEntry sequence 

c1 = c.SetColorEntry(1,"1,2,3")
TypeError: Invalid values in ColorEntry sequence 

c1 = c.SetColorEntry(1,[255,128,0,0])
TypeError: Invalid values in ColorEntry sequence 

c1 = c.SetColorEntry(1,[1,1,1,1])
TypeError: Invalid values in ColorEntry sequence 

from array import array
c1 = c.SetColorEntry(1,array("h",[255,128,0,0]))
TypeError: Invalid values in ColorEntry sequence 

c1 = c.SetColorEntry(1,{"c1":255,"c2":128,"c3":0,"c4":0})
TypeError: not a sequence

c1 = c.SetColorEntry(1,(255,128,0,0))
TypeError: not a sequence

c1 = c.SetColorEntry(1,"255,128,0")
TypeError: ColorEntry sequence too long

c1 = c.SetColorEntry(1,"1")
TypeError: ColorEntry sequence too short

c1 = c.SetColorEntry(1,1,1)
TypeError: ColorTable_SetColorEntry() takes exactly 3 arguments (4 given)

c1 = c.SetColorEntry(1,1)
TypeError: not a sequence

c1 = c.SetColorEntry(1,struct.pack("hhh",1,1,1))
TypeError: ColorEntry sequence too long



What is GDALColorEntry expecting and how to produce this from python but, maybe more importantly, why isn't it obvious? It seems like most of the above should just work.

According to the GDALColorEntry code below, it myst be a tuple of 3 or 4 short ints. 

%typemap(in) GDALColorEntry* (GDALColorEntry ce)
{
  /* %typemap(in) GDALColorEntry* */
   ce.c4 = 255;
  if (! PySequence_Check($input) ) {
    PyErr_SetString(PyExc_TypeError, "not a sequence");
    SWIG_fail;
  }
   int size = PySequence_Size($input);
   if ( size > 4 ) {
     PyErr_SetString(PyExc_TypeError, "ColorEntry sequence too long");
     SWIG_fail;
   }
   if ( size < 3 ) {
     PyErr_SetString(PyExc_TypeError, "ColorEntry sequence too short");
     SWIG_fail;
   }
   if ( !PyArg_ParseTuple( $input,"hhh|h", &ce.c1, &ce.c2, &ce.c3, &ce.c4 ) ) {
     PyErr_SetString(PyExc_TypeError, "Invalid values in ColorEntry sequence ");
     SWIG_fail;
   }
   $1 = &ce;
}


--nix

On Mar 8, 2013, at 22:52, robert <robert at urban4m.com> wrote:

> Frank,
> 
> Thanks for the response.
> 
> I've tried variations of [] and (), with and without alpha (3 or 4 values), and with various values ranging from 0 to 255. They all have failed so it seems i'm doing something fundamentally wrong.
> 
> 
> Traceback (most recent call last):
>   File "makecolortable.py", line 13, in <module>
>     c.CreateColorRamp(1,n,65535,m)
>   File "/usr/lib/python2.7/dist-packages/osgeo/gdal.py", line 1117, in CreateColorRamp
>     return _gdal.ColorTable_CreateColorRamp(self, *args)
> TypeError: not a sequence
> 
> 
> Traceback (most recent call last):
>   File "makecolortable.py", line 11, in <module>
>     n = c.SetColorEntry(1,[0,0,0])
>   File "/usr/lib/python2.7/dist-packages/osgeo/gdal.py", line 1113, in SetColorEntry
>     return _gdal.ColorTable_SetColorEntry(self, *args)
> TypeError: Invalid values in ColorEntry sequence 
> 
> 
> 
> import numpy as np
> import gdal
> 
> driver = gdal.GetDriverByName('GTiff')
> dst_ds = driver.Create('testcolor.tif', 100, 100, 1, gdal.GDT_UInt16)
> 
> band = dst_ds.GetRasterBand(1)
> band.SetRasterColorInterpretation(gdal.GCI_PaletteIndex)
> 
> c = gdal.ColorTable(gdal.GCI_PaletteIndex)
> n = c.SetColorEntry(1,[0,0,0])
> m = c.SetColorEntry(65535,[0,0,0])
> c.CreateColorRamp(1,n,65535,m)
> band.SetColorTable(c)
> 
> --nix
> 
> On 2013/03/08, at 19:09, Frank Warmerdam <warmerdam at pobox.com> wrote:
> 
>> On Fri, Mar 8, 2013 at 2:05 PM, Robert Nix <robert at urban4m.com> wrote:
>>> Let me adjust my question. I changed the color-table code to:
>>> 
>>> c = gdal.ColorTable(gdal.GCI_PaletteIndex)
>>> n = c.SetColorEntry(1,[255,128,0,0])
>>> m = c.SetColorEntry(65535,[0,128,255,255])
>>> c.CreateColorRamp(1,n,65535,m)
>>> band.SetColorTable(c)
>>> 
>>> 
>>> I discovered that the 64K colors are due to the UInt16 (tested GDT_Byte and
>>> got 255) so i realized that maybe i need to create a ramp?
>> 
>> Robert,
>> 
>> I will note that the TIFF format does not support "short colormaps".
>> So if the type of the pixel is 8bit byte then the color table will be
>> exactly 256 entries even if you only put in one color.  Frr UInt16 it
>> will be 65536.  Most other colormap supporting formats do not impose
>> this.
>> 
>>> But the above code fails with:
>>> 
>>> Traceback (most recent call last):
>>>  File "makecolortable.py", line 14, in <module>
>>>    n = c.SetColorEntry(1,[255,128,0,0])
>>>  File "/usr/lib/python2.7/dist-packages/osgeo/gdal.py", line 1113, in
>>> SetColorEntry
>>>    return _gdal.ColorTable_SetColorEntry(self, *args)
>>> TypeError: Invalid values in ColorEntry sequence
>>> 
>>> 
>>> That sequence appears correct as all four values meet the short requirement,
>>> (i think this is the code that produces the error):
>>> 
>>> if ( !PyArg_ParseTuple( $input,"hhh|h", &ce.c1, &ce.c2, &ce.c3, &ce.c4 ) ) {
>>> 
>>>  PyErr_SetString(PyExc_TypeError, "Invalid values in ColorEntry sequence
>>> ");
>> 
>> 
>> I think the problem is that you switched from tuples to lists (ie.
>> from (r,g,b,a) to [r,g,b,a]).
>> 
>> Also, FYI, TIFF does not support alpha in colormaps.
>> 
>> Best regards,
>> Frank
>> 
>>> --nix
>>> 
>>> On Mar 8, 2013, at 16:35, Robert Nix <robert at urban4m.com> wrote:
>>> 
>>> Hi,
>>> 
>>> I'm trying to add a color table to a 1-band UInt16 GeoTiff with Python as
>>> follows:
>>> 
>>> import numpy as np
>>> import gdal
>>> 
>>> driver = gdal.GetDriverByName('GTiff')
>>> dst_ds = driver.Create('testcolor.tif', 100, 100, 1, gdal.GDT_UInt16)
>>> 
>>> band = dst_ds.GetRasterBand(1)
>>> band.SetRasterColorInterpretation(gdal.GCI_PaletteIndex)
>>> 
>>> c = gdal.ColorTable(gdal.GCI_PaletteIndex)
>>> c.SetColorEntry(1,(255,127,0,63))
>>> band.SetColorTable(c)
>>> 
>>> a = np.random.randint(1,10,size=(100,100))
>>> band.WriteArray(a)
>>> 
>>> dst_ds = None
>>> 
>>> 
>>> The problem is that when i run gdalinfo on the testcolor.tif, it lists 65535
>>> color table entries:
>>> 
>>> Driver: GTiff/GeoTIFF
>>> Files: testcolor.tif
>>>       testcolor.tif.aux.xml
>>> Size is 100, 100
>>> Coordinate System is `'
>>> Image Structure Metadata:
>>>  INTERLEAVE=BAND
>>> Corner Coordinates:
>>> Upper Left  (    0.0,    0.0)
>>> Lower Left  (    0.0,  100.0)
>>> Upper Right (  100.0,    0.0)
>>> Lower Right (  100.0,  100.0)
>>> Center      (   50.0,   50.0)
>>> Band 1 Block=100x40 Type=UInt16, ColorInterp=Palette
>>>  Color Table (RGB with 65536 entries)
>>>    0: 1,0,0,255
>>>    1: 1,0,0,255
>>>    2: 0,0,0,255
>>>    3: 0,0,0,255
>>> ...
>>>  65533: 0,0,0,255
>>>  65534: 0,0,0,255
>>>  65535: 0,0,0,255
>>> 
>>> 
>>> What's going on … besides the fact that maybe i'm not understanding
>>> color-tables? If it's clear i don't understand, is there a good resource for
>>> understanding color-tables? Or must I go learn the source code (which i
>>> really don't have to do)?
>>> 
>>> Thanks
>>> --nix
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> gdal-dev mailing list
>>> gdal-dev at lists.osgeo.org
>>> http://lists.osgeo.org/mailman/listinfo/gdal-dev
>> 
>> 
>> 
>> -- 
>> ---------------------------------------+--------------------------------------
>> I set the clouds in motion - turn up   | Frank Warmerdam, warmerdam at pobox.com
>> light and sound - activate the windows | http://pobox.com/~warmerdam
>> and watch the world go round - Rush    | Geospatial Software Developer
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20130310/517f5388/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 1437 bytes
Desc: not available
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20130310/517f5388/attachment.bin>


More information about the gdal-dev mailing list