From 8a67f007f71afdbff9ff8103076ad3ad692e20ac Mon Sep 17 00:00:00 2001 From: Matt Savoie Date: Thu, 19 Dec 2024 13:28:01 -0700 Subject: [PATCH 1/4] DAS-2280: Merge TRANSPARENT_IDX and NODATA_IDX to increase available colors --- CHANGELOG.md | 8 ++++++++ hybig/browse.py | 14 ++++++-------- hybig/color_utility.py | 3 --- tests/unit/test_browse.py | 6 +++--- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ce6c2e..ef4b54c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ 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. + - The user visible change is that now a paletted output PNG will have up to 254 color values and a 255th value that is transparent. + - Internally, the code change removes `TRANSPARENT_IDX` (254) and uses `NODATA_IDX` in its stead. A color of (0,0,0,0) was already set to both of the indexes in the ouput PNGs. This ensures the roundtrip from single band to RGBA to Paletted PNG is consistent. + ## [v2.1.0] - 2024-12-13 ### Changed diff --git a/hybig/browse.py b/hybig/browse.py index 8c120fd..2246666 100644 --- a/hybig/browse.py +++ b/hybig/browse.py @@ -28,8 +28,6 @@ NODATA_RGBA, OPAQUE, TRANSPARENT, - TRANSPARENT_IDX, - TRANSPARENT_RGBA, all_black_color_map, get_color_palette, palette_from_remote_colortable, @@ -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) @@ -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)) @@ -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 diff --git a/hybig/color_utility.py b/hybig/color_utility.py index 4efdd68..921ff0d 100644 --- a/hybig/color_utility.py +++ b/hybig/color_utility.py @@ -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 diff --git a/tests/unit/test_browse.py b/tests/unit/test_browse.py index 4f9c1c2..12161a5 100644 --- a/tests/unit/test_browse.py +++ b/tests/unit/test_browse.py @@ -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) @@ -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) From 0d66d86c35f5ce139b93eea53329a422690485c6 Mon Sep 17 00:00:00 2001 From: Matt Savoie Date: Thu, 19 Dec 2024 15:06:52 -0700 Subject: [PATCH 2/4] DAS-2280: Bump service version and update CHANGELOG --- CHANGELOG.md | 3 ++- docker/service_version.txt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef4b54c..8f2c8ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ Changelog](http://keepachangelog.com/en/1.0.0/). ### Changed -* NODATA and TRANSPARENT values are merged. +* NODATA and TRANSPARENT values are merged. [[#41](https://github.com/nasa/harmony-browse-image-generator/pull/41)] - The user visible change is that now a paletted output PNG will have up to 254 color values and a 255th value that is transparent. - Internally, the code change removes `TRANSPARENT_IDX` (254) and uses `NODATA_IDX` in its stead. A color of (0,0,0,0) was already set to both of the indexes in the ouput PNGs. This ensures the roundtrip from single band to RGBA to Paletted PNG is consistent. @@ -100,6 +100,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 diff --git a/docker/service_version.txt b/docker/service_version.txt index 7ec1d6d..ccbccc3 100644 --- a/docker/service_version.txt +++ b/docker/service_version.txt @@ -1 +1 @@ -2.1.0 +2.2.0 From 78ee92c5267c0953929d11523a5ab48d0cdb252e Mon Sep 17 00:00:00 2001 From: Matt Savoie Date: Thu, 19 Dec 2024 15:08:07 -0700 Subject: [PATCH 3/4] DAS-2280: Tweak CHANGELOG --- CHANGELOG.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f2c8ab..bbbab89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,21 +9,26 @@ Changelog](http://keepachangelog.com/en/1.0.0/). ### Changed * NODATA and TRANSPARENT values are merged. [[#41](https://github.com/nasa/harmony-browse-image-generator/pull/41)] - - The user visible change is that now a paletted output PNG will have up to 254 color values and a 255th value that is transparent. - - Internally, the code change removes `TRANSPARENT_IDX` (254) and uses `NODATA_IDX` in its stead. A color of (0,0,0,0) was already set to both of the indexes in the ouput PNGs. This ensures the roundtrip from single band to RGBA to Paletted PNG is consistent. + - 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 From 189ed212957a5b7c17c529023a0bf8c7b8588cd9 Mon Sep 17 00:00:00 2001 From: Matt Savoie Date: Fri, 20 Dec 2024 13:28:44 -0700 Subject: [PATCH 4/4] DAS-2280: Fix typo and make random type explicit. --- CHANGELOG.md | 2 +- tests/unit/test_browse.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbbab89..a89247a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ Changelog](http://keepachangelog.com/en/1.0.0/). `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. + paletted PNG is consistent. ## [v2.1.0] - 2024-12-13 diff --git a/tests/unit/test_browse.py b/tests/unit/test_browse.py index 12161a5..897149c 100644 --- a/tests/unit/test_browse.py +++ b/tests/unit/test_browse.py @@ -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) @@ -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, :, :]) @@ -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' @@ -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' @@ -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) @@ -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') @@ -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