cogeotiff / rio-cogeo

Cloud Optimized GeoTIFF creation and validation plugin for rasterio
https://cogeotiff.github.io/rio-cogeo/
BSD 3-Clause "New" or "Revised" License
308 stars 42 forks source link

Colormap extended to 255 #287

Closed HamedAlemo closed 3 months ago

HamedAlemo commented 4 months ago

Hi All, We are translating some GeoTIFF files to COG using cog_translate. We pass a colormap as following to the function, and the resulting file is validated as COG. But when we load it in QGIS the colormap is extended to 255 while there are no pixels with values greater than 6 in the file. Is there a way to avoid this?

landcover_cmap = {
            1: (36, 78, 12), 
            2: (105, 183, 146),
            3: (222, 90, 32),
            4: (125, 125, 255),
            5: (245, 228, 131),
            6: (245, 228, 131)
        }
src_path = <path to source file>
out_path = <path to output file>
compress_profile = compress_profile = cog_profiles.get("lzw")
cog_translate(src_path, out_path, compress_profile, forward_band_tags=True, colormap = landcover_cmap, quiet=True)

The palette in QGIS shows up as this:

Screenshot 2024-04-29 at 4 58 12 PM
vincentsarago commented 4 months ago

@HamedAlemo I'm pretty sure this is a BUG with the GDAL GDALCreateCopy method. you might want to open an issue in the GDAL or rasterio repo


from rasterio.io import MemoryFile
from rasterio.shutil import copy
from affine import Affine

profile = {
        "driver": "GTiff",
        "count": 1,
        "dtype": "uint8",
        "height": 512,
        "width": 512,
        "crs": "epsg:4326",
        "transform": Affine(0.703125, 0.0, -180.0, 0.0, -0.3515625, 90.0),
}

with MemoryFile() as memfile_int:
    with memfile_int.open(**profile) as src:
        src.write_colormap(1, {0: (255, 0, 0, 255), 1: (0, 0, 0, 0)})
        print(min(src.colormap(1)), max(src.colormap(1)))

        out_profile = profile
        with MemoryFile() as memfile_out:
            copy(src, memfile_out.name, **profile)
            with memfile_out.open() as dst:
                print(min(dst.colormap(1)), max(dst.colormap(1)))

0 1
0 255
HamedAlemo commented 3 months ago

Thanks @vincentsarago for looking into this. I'll submit an issue w rasterio.