Skip to content

Commit

Permalink
Fix alpha band values when storing Uint16 data in PNG (#407)
Browse files Browse the repository at this point in the history
* Fix alpha band values when storing `Uint16` data in **PNG**

* make sure we keep even distribution of alpha values
  • Loading branch information
vincentsarago authored Jul 29, 2021
1 parent 26d4733 commit 641d5a2
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
4 changes: 3 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Unreleased
## 2.1.1 (2021-07-29)

* add support for setting the S3 endpoint url via the `AWS_S3_ENDPOINT` environment variables in `aws_get_object` function using boto3 (https://github.com/cogeotiff/rio-tiler/pull/394)
* make `ImageStatistics.valid_percent` a value between 0 and 100 (instead of 0 and 1) (author @param-thakker, https://github.com/cogeotiff/rio-tiler/pull/400)
Expand All @@ -9,6 +9,8 @@
pass
```

* Fix alpha band values when storing `Uint16` data in **PNG**. (https://github.com/cogeotiff/rio-tiler/pull/407)

## 2.1.0 (2021-05-17)

* add auto-rescaling in `ImageData.render` method to avoid error when datatype is not supported by the output driver (https://github.com/cogeotiff/rio-tiler/pull/391)
Expand Down
3 changes: 3 additions & 0 deletions rio_tiler/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,9 @@ def render(
if img_format == "WEBP" and data.shape[0] == 1:
data = numpy.repeat(data, 3, axis=0)

if img_format == "PNG" and data.dtype == "uint16" and mask is not None:
mask = linear_rescale(mask, (0, 255), (0, 65535)).astype("uint16")

elif img_format == "JPEG":
mask = None

Expand Down
40 changes: 40 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
"""Test rio_tiler.models."""

from io import BytesIO

import numpy
import pytest
import rasterio

from rio_tiler.errors import InvalidDatatypeWarning
from rio_tiler.models import ImageData
Expand Down Expand Up @@ -53,3 +56,40 @@ def test_imageData_AutoRescalingAllTypes(dtype):
ImageData(numpy.zeros((3, 256, 256), dtype=dtype)).render(
img_format="JP2OPENJPEG"
)


def test_16bit_PNG():
"""Uint16 Mask value should be between 0 and 65535 for PNG."""
mask = numpy.zeros((256, 256), dtype="uint16") + 255
mask[0:10, 0:10] = 0
mask[10:11, 10:11] = 100

with pytest.warns(None):
img = ImageData(numpy.zeros((1, 256, 256), dtype="uint16"), mask,).render(
img_format="PNG"
)

with rasterio.open(BytesIO(img)) as src:
assert src.count == 2
assert src.meta["dtype"] == "uint16"
arr = src.read(2)
assert arr.min() == 0
assert arr.max() == 65535
assert (arr[0:10, 0:10] == 0).all()
assert (arr[10:11, 10:11] == 25700).all()
assert (arr[11:, 11:] == 65535).all()

with pytest.warns(None):
img = ImageData(numpy.zeros((3, 256, 256), dtype="uint16"), mask,).render(
img_format="PNG"
)

with rasterio.open(BytesIO(img)) as src:
assert src.count == 4
assert src.meta["dtype"] == "uint16"
arr = src.read(4)
assert arr.min() == 0
assert arr.max() == 65535
assert (arr[0:10, 0:10] == 0).all()
assert (arr[10:11, 10:11] == 25700).all()
assert (arr[11:, 11:] == 65535).all()

0 comments on commit 641d5a2

Please sign in to comment.