Skip to content

Commit

Permalink
DAS-2280: Merge TRANSPARENT_IDX and NODATA_IDX to increase available … (
Browse files Browse the repository at this point in the history
  • Loading branch information
flamingbear authored Dec 20, 2024
1 parent 3d474ec commit d05dc65
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 27 deletions.
24 changes: 19 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,31 @@ HyBIG follows semantic versioning. All notable changes to this project will be
documented in this file. The format is based on [Keep a
Changelog](http://keepachangelog.com/en/1.0.0/).

## [v2.2.0] - 2024-12-19

### Changed

* NODATA and TRANSPARENT values are merged. [[#41](https://github.com/nasa/harmony-browse-image-generator/pull/41)]
- User visible change: paletted PNG outupt images will have up to 254 color
values and a 255th value that is transparent.
- Internal code changes: removes `TRANSPARENT_IDX` (254) and uses
`NODATA_IDX` (255) in its stead. A color of (0,0,0,0) was previosly set to
both the indexes (254 and 255) in the ouput PNGs and now only 255 will have
this value. This change ensures the roundtrip from single band to RGBA to
paletted PNG is consistent.

## [v2.1.0] - 2024-12-13

### Changed

* Input GeoTIFF RGB[A] images are **no longer palettized** when converted to a PNG. The new resulting output browse images are now 3 or 4 band PNG retaining the color information of the input image.[#39](https://github.com/nasa/harmony-browse-image-generator/pull/39)
* Changed pre-commit configuration to remove `black-jupyter` dependency [#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)
* Updates service image's python to 3.12 [#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)
* Simplifies test scripts to run with pytest and pytest plugins [#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)
* Input GeoTIFF RGB[A] images are **no longer palettized** when converted to a PNG. The new resulting output browse images are now 3 or 4 band PNG retaining the color information of the input image.[[#39](https://github.com/nasa/harmony-browse-image-generator/pull/39)]
* Changed pre-commit configuration to remove `black-jupyter` dependency [[#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)]
* Updates service image's python to 3.12 [[#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)]
* Simplifies test scripts to run with pytest and pytest plugins [[#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)]

### Removed

* Removes `test_code_format.py` in favor of `ruff` pre-commit configuration [#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)
* Removes `test_code_format.py` in favor of `ruff` pre-commit configuration [[#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)]


## [v2.0.2] - 2024-10-15
Expand Down Expand Up @@ -92,6 +105,7 @@ For more information on internal releases prior to NASA open-source approval,
see legacy-CHANGELOG.md.

[unreleased]: https://github.com/nasa/harmony-browse-image-generator/
[v2.2.0]: https://github.com/nasa/harmony-browse-image-generator/releases/tag/2.2.0
[v2.1.0]: https://github.com/nasa/harmony-browse-image-generator/releases/tag/2.1.0
[v2.0.2]: https://github.com/nasa/harmony-browse-image-generator/releases/tag/2.0.2
[v2.0.1]: https://github.com/nasa/harmony-browse-image-generator/releases/tag/2.0.1
Expand Down
2 changes: 1 addition & 1 deletion docker/service_version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.1.0
2.2.0
14 changes: 6 additions & 8 deletions hybig/browse.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
NODATA_RGBA,
OPAQUE,
TRANSPARENT,
TRANSPARENT_IDX,
TRANSPARENT_RGBA,
all_black_color_map,
get_color_palette,
palette_from_remote_colortable,
Expand Down Expand Up @@ -299,7 +297,7 @@ def convert_gray_1band_to_raster(data_array: DataArray) -> ndarray:
"""Convert a 1-band raster without a color association."""
band = data_array[0, :, :]
cmap = matplotlib.colormaps['Greys_r']
cmap.set_bad(TRANSPARENT_RGBA)
cmap.set_bad(NODATA_RGBA)
norm = Normalize(vmin=np.nanmin(band), vmax=np.nanmax(band))
scalar_map = ScalarMappable(cmap=cmap, norm=norm)

Expand Down Expand Up @@ -403,9 +401,9 @@ def palettize_raster(raster: ndarray) -> tuple[ndarray, dict]:
written to the final raster as 254 and add the mapped RGBA value to the
color palette.
"""
# reserves 254 for transparent images and 255 for off grid fill values
# 0 to 253
max_colors = 254
# reserves 255 for transparent and off grid fill values
# 0 to 254
max_colors = 255
rgb_raster, alpha = remove_alpha(raster)

multiband_image = Image.fromarray(reshape_as_image(rgb_raster))
Expand All @@ -427,8 +425,8 @@ def add_alpha(
"""
if alpha is not None and np.any(alpha != OPAQUE):
# Set any alpha to the transparent index value
quantized_array = np.where(alpha != OPAQUE, TRANSPARENT_IDX, quantized_array)
color_map[TRANSPARENT_IDX] = TRANSPARENT_RGBA
quantized_array = np.where(alpha != OPAQUE, NODATA_IDX, quantized_array)
color_map[NODATA_IDX] = NODATA_RGBA
return quantized_array, color_map


Expand Down
3 changes: 0 additions & 3 deletions hybig/color_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
# Applied to transparent pixels where alpha < 255
TRANSPARENT = np.uint8(0)
OPAQUE = np.uint8(255)
TRANSPARENT_RGBA = (0, 0, 0, 0)
TRANSPARENT_IDX = 254

# Applied to off grid areas during reprojection
NODATA_RGBA = (0, 0, 0, 0)
NODATA_IDX = 255
Expand Down
20 changes: 10 additions & 10 deletions tests/unit/test_browse.py
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ def test_convert_5_multiband_to_raster(self):
)

def test_standardize_raster_for_writing_jpeg_3band(self):
raster = self.random.integers(255, size=(3, 5, 6))
raster = self.random.integers(255, size=(3, 5, 6), dtype='uint8')
count = 'irrelevant'
driver = 'JPEG'
expected_raster = np.copy(raster)
Expand All @@ -667,7 +667,7 @@ def test_standardize_raster_for_writing_jpeg_3band(self):
np.testing.assert_array_equal(expected_raster, actual_raster, strict=True)

def test_standardize_raster_for_writing_jpeg_4band(self):
raster = self.random.integers(255, size=(4, 7, 8))
raster = self.random.integers(255, size=(4, 7, 8), dtype='uint8')
driver = 'JPEG'
count = 'irrelevant'
expected_raster = np.copy(raster[0:3, :, :])
Expand All @@ -680,7 +680,7 @@ def test_standardize_raster_for_writing_jpeg_4band(self):

@patch('hybig.browse.palettize_raster')
def test_standardize_raster_for_writing_png_4band(self, palettize_mock):
raster = self.random.integers(255, size=(4, 7, 8))
raster = self.random.integers(255, size=(4, 7, 8), dtype='uint8')
driver = 'PNG'
count = 'not 1'

Expand All @@ -690,7 +690,7 @@ def test_standardize_raster_for_writing_png_4band(self, palettize_mock):

@patch('hybig.browse.palettize_raster')
def test_standardize_raster_for_writing_png_3band(self, palettize_mock):
raster = self.random.integers(255, size=(3, 7, 8))
raster = self.random.integers(255, size=(3, 7, 8), dtype='uint8')
driver = 'PNG'
count = 'not 1'

Expand All @@ -700,7 +700,7 @@ def test_standardize_raster_for_writing_png_3band(self, palettize_mock):

@patch('hybig.browse.palettize_raster')
def test_prepare_1band_raster_for_writing_png(self, palettize_mock):
raster = self.random.integers(255, size=(1, 7, 8))
raster = self.random.integers(255, size=(1, 7, 8), dtype='uint8')
driver = 'PNG'
count = 1
palettize_mock.return_value = (None, None)
Expand All @@ -711,7 +711,7 @@ def test_prepare_1band_raster_for_writing_png(self, palettize_mock):
@patch('hybig.browse.get_color_map_from_image')
def test_palettize_raster_no_alpha_layer(self, get_color_map_mock, image_mock):
"""Test that the quantize function is called by a correct image."""
raster = self.random.integers(255, dtype='uint8', size=(3, 10, 11))
raster = self.random.integers(255, size=(3, 10, 11), dtype='uint8')

quantized_output = Image.fromarray(
self.random.integers(254, size=(10, 11), dtype='uint8')
Expand All @@ -724,7 +724,7 @@ def test_palettize_raster_no_alpha_layer(self, get_color_map_mock, image_mock):

out_raster, out_map = palettize_raster(raster)

multiband_image_mock.quantize.assert_called_once_with(colors=254)
multiband_image_mock.quantize.assert_called_once_with(colors=255)
get_color_map_mock.assert_called_once_with(quantized_output)

np.testing.assert_array_equal(expected_out_raster, out_raster, strict=True)
Expand All @@ -733,7 +733,7 @@ def test_palettize_raster_no_alpha_layer(self, get_color_map_mock, image_mock):
@patch('hybig.browse.get_color_map_from_image')
def test_palettize_raster_with_alpha_layer(self, get_color_map_mock, image_mock):
"""Test that the quantize function is called by a correct image."""
raster = self.random.integers(255, dtype='uint8', size=(4, 10, 11))
raster = self.random.integers(255, size=(4, 10, 11), dtype='uint8')
# No transparent pixels
raster[3, :, :] = 255

Expand All @@ -748,11 +748,11 @@ def test_palettize_raster_with_alpha_layer(self, get_color_map_mock, image_mock)
multiband_image_mock.quantize.return_value = quantized_output

expected_out_raster = np.array(quantized_output).reshape(1, 10, 11)
expected_out_raster[0, 0:3, 0:3] = 254
expected_out_raster[0, 0:3, 0:3] = 255

out_raster, out_map = palettize_raster(raster)

multiband_image_mock.quantize.assert_called_once_with(colors=254)
multiband_image_mock.quantize.assert_called_once_with(colors=255)
get_color_map_mock.assert_called_once_with(quantized_output)

np.testing.assert_array_equal(expected_out_raster, out_raster, strict=True)
Expand Down

0 comments on commit d05dc65

Please sign in to comment.