diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index 3b4dd4c75b5d..2b85923f5499 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -215,17 +215,16 @@ def _resample( return out -def _rgb_to_rgba(A): +def _rgb_to_rgba(A, alpha=None): """ Convert an RGB image to RGBA, as required by the image resample C++ extension. """ rgba = np.zeros((A.shape[0], A.shape[1], 4), dtype=A.dtype) + if alpha is None or np.ndim(alpha) == 0: + alpha = 255 if A.dtype == np.uint8 else 1.0 rgba[:, :, :3] = A - if rgba.dtype == np.uint8: - rgba[:, :, 3] = 255 - else: - rgba[:, :, 3] = 1.0 + rgba[:, :, 3] = alpha return rgba @@ -582,7 +581,13 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0, else: if A.ndim == 2: # interpolation_stage = 'rgba' self.norm.autoscale_None(A) - A = self.to_rgba(A) + A = self.to_rgba(A, alpha=self.get_alpha()) + elif A.shape[2] == 3: + A = _rgb_to_rgba(A, alpha=self.get_alpha()) + elif A.shape[2] == 4: + array_alpha = self.get_alpha() + if array_alpha is not None and np.ndim(array_alpha) != 0: + A[:, :, 3] *= array_alpha # blend alphas of image and param alpha = self._get_scalar_alpha() if A.shape[2] == 3: # No need to resample alpha or make a full array; NumPy will expand diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.pdf b/lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.pdf new file mode 100644 index 000000000000..7f1b7db04987 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.pdf differ diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.png b/lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.png new file mode 100644 index 000000000000..51af9d271a34 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.svg b/lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.svg new file mode 100644 index 000000000000..8576ae138cac --- /dev/null +++ b/lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.svg @@ -0,0 +1,215 @@ + + + + + + + + 2023-08-16T01:06:38.056103 + image/svg+xml + + + Matplotlib v3.8.0.dev1806+g848100f03e.d20230815, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index 4340be96a38b..225e3b9c124c 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -255,6 +255,22 @@ def test_image_alpha(): ax3.imshow(Z, alpha=0.5, interpolation='nearest') +@image_comparison(['image_alpha_array'], remove_text=True) +def test_image_alpha_array(): + _, ax = plt.subplots() + + # create a 2x2 grid. If alpha is applying correctly, + # the top half should not match the 0.5 valued pixel + # in the bottom half. + arr = np.array([[.5, .5], [.75, .5]]) + cmap = plt.get_cmap('gray') + norm = colors.Normalize() + arr_rgb = cmap(norm(arr))[:, :, :3] + alpha = np.ones_like(arr) + alpha[:1] = 0.2 + ax.imshow(arr, alpha=alpha, cmap='gray', interpolation='none') + + @mpl.style.context('mpl20') @check_figures_equal(extensions=['png']) def test_imshow_alpha(fig_test, fig_ref):