Ejemplo n.º 1
0
def colormap(*,
             stretch_range: Tuple[Number, Number],
             colormap: str = None,
             num_values: int = 255) -> List[Dict[str, Any]]:
    """Returns a list [{value=pixel value, rgba=rgba tuple}] for given stretch parameters"""
    from terracotta import image

    target_coords = np.linspace(stretch_range[0], stretch_range[1], num_values)

    if colormap is not None:
        from terracotta.cmaps import get_cmap
        cmap = get_cmap(colormap)
    else:
        # assemble greyscale cmap of shape (255, 4)
        cmap = np.ones(shape=(255, 4), dtype='uint8') * 255
        cmap[:, :-1] = np.tile(
            np.arange(1, 256, dtype='uint8')[:, np.newaxis], (1, 3))

    cmap_coords = image.to_uint8(target_coords, *stretch_range) - 1
    colors = cmap[cmap_coords]

    return [
        dict(value=p, rgba=c)
        for p, c in zip(target_coords.tolist(), colors.tolist())
    ]
Ejemplo n.º 2
0
def test_colormap_range(stretch_range):
    """Ensure that all colors from colormap file are present in returned data"""
    from terracotta.cmaps import get_cmap
    from terracotta.handlers import colormap
    cmap_name = 'jet'
    cmap_in = get_cmap(cmap_name)
    num_values = cmap_in.shape[0]
    cmap_out = colormap.colormap(colormap=cmap_name, stretch_range=stretch_range,
                                 num_values=num_values)
    cmap_out_arr = np.array([val['rgba'] for val in cmap_out], dtype=cmap_in.dtype)
    np.testing.assert_array_equal(cmap_in, cmap_out_arr)
Ejemplo n.º 3
0
def test_get_cmap():
    from terracotta.cmaps import get_cmap
    cmap = get_cmap('jet')
    assert cmap.shape == (255, 3)
    assert cmap.dtype == np.uint8
Ejemplo n.º 4
0
def array_to_png(img_data: Array,
                 colormap: Union[str, Palette, None] = None) -> BinaryIO:
    """Encode an 8bit array as PNG"""
    from terracotta.cmaps import get_cmap

    transparency: Union[Tuple[int, int, int], int, bytes]

    settings = get_settings()
    compress_level = settings.PNG_COMPRESS_LEVEL

    if img_data.ndim == 3:  # encode RGB image
        if img_data.shape[-1] != 3:
            raise ValueError('3D input arrays must have three bands')

        if colormap is not None:
            raise ValueError(
                'Colormap argument cannot be given for multi-band data')

        mode = 'RGB'
        transparency = (0, 0, 0)
        palette = None

    elif img_data.ndim == 2:  # encode paletted image
        mode = 'L'

        if colormap is None:
            palette = None
            transparency = 0
        else:
            if isinstance(colormap, str):
                # get and apply colormap by name
                try:
                    cmap_vals = get_cmap(colormap)
                except ValueError as exc:
                    raise exceptions.InvalidArgumentsError(
                        f'Encountered invalid color map {colormap}') from exc
                palette = np.concatenate(
                    (np.zeros(3, dtype='uint8'), cmap_vals[:, :-1].flatten()))
                transparency_arr = np.concatenate(
                    (np.zeros(1, dtype='uint8'), cmap_vals[:, -1]))
            else:
                # explicit mapping
                if len(colormap) > 255:
                    raise exceptions.InvalidArgumentsError(
                        'Explicit color map must contain less than 256 values')

                colormap_array = np.asarray(colormap, dtype='uint8')
                if colormap_array.ndim != 2 or colormap_array.shape[1] != 4:
                    raise ValueError(
                        'Explicit color mapping must have shape (n, 4)')

                rgb, alpha = colormap_array[:, :-1], colormap_array[:, -1]
                palette = np.concatenate(
                    (np.zeros(3, dtype='uint8'), rgb.flatten(),
                     np.zeros(3 * (256 - len(colormap) - 1), dtype='uint8')))

                # PIL expects paletted transparency as raw bytes
                transparency_arr = np.concatenate(
                    (np.zeros(1, dtype='uint8'), alpha,
                     np.zeros(256 - len(colormap) - 1, dtype='uint8')))

            assert transparency_arr.shape == (256, )
            assert transparency_arr.dtype == 'uint8'
            transparency = transparency_arr.tobytes()

            assert palette.shape == (3 * 256, ), palette.shape
    else:
        raise ValueError('Input array must have 2 or 3 dimensions')

    if isinstance(img_data, np.ma.MaskedArray):
        img_data = img_data.filled(0)

    img = Image.fromarray(img_data, mode=mode)

    if palette is not None:
        img.putpalette(palette)

    sio = BytesIO()
    img.save(sio,
             'png',
             compress_level=compress_level,
             transparency=transparency)
    sio.seek(0)
    return sio
Ejemplo n.º 5
0
def test_get_cmap():
    from terracotta.cmaps import get_cmap, AVAILABLE_CMAPS
    for name in AVAILABLE_CMAPS:
        cmap = get_cmap(name)
        assert cmap.shape == (255, 3)
        assert cmap.dtype == np.uint8