From 9f51cda5cb6818ab3735f850046bb4790e346af2 Mon Sep 17 00:00:00 2001 From: Ammar Alam Date: Mon, 14 Aug 2023 19:35:27 +0500 Subject: [PATCH 1/5] Add alpha-array support to _rgb_to_rgba --- lib/matplotlib/image.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index 757f0ba3476e..f342cdc5ce36 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -214,17 +214,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: + 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 @@ -554,12 +553,12 @@ 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) - if A.shape[2] == 3: - A = _rgb_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()) alpha = self._get_scalar_alpha() output_alpha = _resample( # resample alpha channel - self, A[..., 3], out_shape, t, alpha=alpha) + self, A[..., 3], out_shape, t, alpha=1.0) output = _resample( # resample rgb channels self, _rgb_to_rgba(A[..., :3]), out_shape, t, alpha=alpha) output[..., 3] = output_alpha # recombine rgb and alpha From ce6efd3f4111c9025840a3692647238d74dc3a28 Mon Sep 17 00:00:00 2001 From: Ammar Alam Date: Mon, 14 Aug 2023 23:44:57 +0500 Subject: [PATCH 2/5] Remove hardcoded value used in testing --- lib/matplotlib/image.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index f342cdc5ce36..152cea83356a 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -558,7 +558,7 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0, A = _rgb_to_rgba(A, alpha=self.get_alpha()) alpha = self._get_scalar_alpha() output_alpha = _resample( # resample alpha channel - self, A[..., 3], out_shape, t, alpha=1.0) + self, A[..., 3], out_shape, t, alpha=alpha) output = _resample( # resample rgb channels self, _rgb_to_rgba(A[..., :3]), out_shape, t, alpha=alpha) output[..., 3] = output_alpha # recombine rgb and alpha From 848100f03e497db0ad173012ca89bed5caee55cc Mon Sep 17 00:00:00 2001 From: Ammar Alam Date: Tue, 15 Aug 2023 00:35:42 +0500 Subject: [PATCH 3/5] Added test for alpha array --- .../test_image/image_alpha_array.pdf | Bin 0 -> 1748 bytes .../test_image/image_alpha_array.png | Bin 0 -> 3816 bytes lib/matplotlib/tests/test_image.py | 16 ++++++++++++++++ 3 files changed, 16 insertions(+) create mode 100644 lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.pdf create mode 100644 lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.png 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 0000000000000000000000000000000000000000..7f1b7db04987813e373b35d70c5666b990943588 GIT binary patch literal 1748 zcmZ`)eQXnD9ByMY;rt?CVlXOi%$kkJ_TGE_SW70_kChEYx_0bC9CEw9Z4cVJ<>)L5;puwCf$7BYj5jz^ZG}7 zzkA;MeLTiu3l0QjNdtBr02_8T@56!y%5%4s8Esoc<24K%xj=~5G^|L#NpBe#N$^oo ziUU{vsUiyztbyGmZ6HWW!5Iy}>J%x#m;d(XzpFu0K{?3W0Ii!=uV7MLu6!8As+?8? z(hsda4B!qN6?vbWAsJcnahAJ)!_I*w2Kq@;z@huZEOWG;>P*7>$~;}5PK5T2X1 zt`!D=+sj z_J($x{?$EsmH+zeXw~Ixr2WyFY4)$q4TIONRCRsqXm6~KWFFxguYYyrxYE$dJbwJm zvx8^4u6|;@dF#Q>le5KpKOC0kiyHp!zJKJO&wgv2+f+9@vHq>0zWQ$yH{S3UZyBCh z^T3{sJzos}a+jHU=kqP4=Q}6*I*PiKJMPw#CHJ10pV(g4`|0eZvgx+po&ARfHt$Lv zt-0Bre5}JZzPW!)dUh;&ED$^La_ z%WJ2;FQb~w4>hk&odL><-Od_{)tRHQ-Gtsej*2!<-jcMbQVmAE2rOA*NzBmiB_Js9 z08vJvm-}BBT7(tIm8##AmwLbyq&_l=sYU?hY_?Ra9xwno=NcA-k#w`Bds#OSfc0XO zsFMS*3XAasF$Gn5QdS}@ynw0as--B-;3$9rd_WX%c$<&(SF*6MV6j*>5x+s7sHq{W z_~lfKEKy$}2CkxVhP;5PotQ7B>XQj6#At#hE7U-_ti((DuXIYH>t&U9>!US1mD?YM z_7Ph4x-Ay#QLA+o0T?7A&fuDwa`~Wgn+?7wMpe?izCyyZOTV0^trhTvRwXQ>;26UK z;SshBz0Yb$N^}FDE%x#yqC8tlMM8dCWOjkKLSub(zl+ zhnVv^%{Y!FD|2Oiq|=o#kBe-?Qd%0ET6mvY_wj cYAGfIodtdOsv56o`uLIE;bCmH%AG;xKNWf&G5`Po literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..51af9d271a3401a0096663adc5ee308080e02c4e GIT binary patch literal 3816 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRz;U%sSCBgY=CFO}lsSLh} zB?US8B{`W%3T3H9#hLke#(EZd26`!}Wrh|8rrPPrsb;BZDaL6ghI%PR21dpP7KSD| z3K=CO1;tkS`nhoJdih1^`Y!}|j{~jXEbxddW?Kh9y6bqo4x!D;}Y$T7eWV1S6w+)`^sURK&(>kC0F(WVU87F!Xi0# zzfsHi)2D3jZ+VqHxFh^beMxoedA%Mm~?Mnt##a<3d3qPc9(_^FLcGa4Ub8zkKZpRE-qet{DVSXUf!{< zU%$SQv=R7TedEsihrj;({9N(%)z$d@hd-?55RluOe}0{wp5C#iPoF+9wQ0G0Ik>#~ zz@7Jr#rxaOe@?G6m0!rrz#z%U#K4fk!ok2WK~Uj9$?2y>-&o`({I<<`C;lUniDgFK z)~K`d4loz(Z$JB&$=A+-J72l zS%$5?y2O>CK;qv1di!m+-fYE%5T=o&0Y%J&5GSpp}ZJvMZ=FOYs>94<5t-1c% zv%5jQu%yJKnu(#mgW=)!!s=@4b?erpoo8TpQ2&92d$h6~Z79&CkyLC`&G2W%bp80g z&6_vBKX>i**NFAkCyOyMeAvvwvA_5B?c0T=rKZ)u*6IId^$23qyr9CU%F#j<-b}=r z7!H)Yzqfa`Eh9q*hd_cAuw?abN9z=T)8_QQb@s<39zQs;`R><=Gj)80ZY~Y2|&T;=jWfFcaYI?*Z%$c=i4&< zJA3!;-5Yt^lQ%~6OrAXXW--G9&l~T*Cj(Ui8x!ZwpHDykumRjhd8}MA+EXF2m-bm* Y@j~sYV>OOaz@|Qfr>mdKI;Vst0QeTpp#T5? literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index aeeebd136b65..0e53cf2cf9df 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -268,6 +268,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') + + def test_cursor_data(): from matplotlib.backend_bases import MouseEvent From 5240fc40f6341c981188007453ec274b1bf2e669 Mon Sep 17 00:00:00 2001 From: Ammar Alam Date: Wed, 16 Aug 2023 01:10:42 +0500 Subject: [PATCH 4/5] Add svg baseline image --- .../test_image/image_alpha_array.svg | 215 ++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 lib/matplotlib/tests/baseline_images/test_image/image_alpha_array.svg 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/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f77ac822d64a82266dd2fdb9fcd7cfc301dc10d0 Mon Sep 17 00:00:00 2001 From: Ammar Alam Date: Sat, 19 Aug 2023 02:20:44 +0500 Subject: [PATCH 5/5] Combine alpha for rgba images. --- lib/matplotlib/image.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index 152cea83356a..d46b109a9de5 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -220,7 +220,7 @@ def _rgb_to_rgba(A, alpha=None): extension. """ rgba = np.zeros((A.shape[0], A.shape[1], 4), dtype=A.dtype) - if alpha is None: + if alpha is None or np.ndim(alpha) == 0: alpha = 255 if A.dtype == np.uint8 else 1.0 rgba[:, :, :3] = A rgba[:, :, 3] = alpha @@ -556,6 +556,10 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0, 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() output_alpha = _resample( # resample alpha channel self, A[..., 3], out_shape, t, alpha=alpha)