@@ -65,6 +65,12 @@ def __init__(self, *args, **kwargs):
6565 # sent to the clients will be a full frame.
6666 self ._force_full = True
6767
68+ # Store the current image mode so that at any point, clients can
69+ # request the information. This should be changed by calling
70+ # self.set_image_mode(mode) so that the notification can be given
71+ # to the connected clients.
72+ self ._current_image_mode = 'full'
73+
6874 def show (self ):
6975 # show the figure window
7076 from matplotlib .pyplot import show
@@ -86,24 +92,41 @@ def draw(self):
8692 def draw_idle (self ):
8793 self .send_event ("draw" )
8894
95+ def set_image_mode (self , mode ):
96+ """
97+ Set the image mode for any subsequent images which will be sent
98+ to the clients. The modes may currently be either 'full' or 'diff'.
99+
100+ Note: diff images may not contain transparency, therefore upon
101+ draw this mode may be changed if the resulting image has any
102+ transparent component.
103+
104+ """
105+ if mode not in ['full' , 'diff' ]:
106+ raise ValueError ('image mode must be either full or diff.' )
107+ if self ._current_image_mode != mode :
108+ self ._current_image_mode = mode
109+ self .handle_send_image_mode (None )
110+
89111 def get_diff_image (self ):
90112 if self ._png_is_old :
113+ renderer = self .get_renderer ()
114+
91115 # The buffer is created as type uint32 so that entire
92116 # pixels can be compared in one numpy call, rather than
93117 # needing to compare each plane separately.
94- renderer = self .get_renderer ()
95118 buff = np .frombuffer (renderer .buffer_rgba (), dtype = np .uint32 )
96-
97119 buff .shape = (renderer .height , renderer .width )
98120
99- # If any pixels have transparency, we need to force a full draw
100- # as we cannot overlay new on top of old.
121+ # If any pixels have transparency, we need to force a full
122+ # draw as we cannot overlay new on top of old.
101123 pixels = buff .view (dtype = np .uint8 ).reshape (buff .shape + (4 ,))
102- some_transparency = np .any (pixels [:, :, 3 ] != 255 )
103-
104- output = buff
105124
106- if not self ._force_full and not some_transparency :
125+ if self ._force_full or np .any (pixels [:, :, 3 ] != 255 ):
126+ self .set_image_mode ('full' )
127+ output = buff
128+ else :
129+ self .set_image_mode ('diff' )
107130 last_buffer = np .frombuffer (self ._last_renderer .buffer_rgba (),
108131 dtype = np .uint32 )
109132 last_buffer .shape = (renderer .height , renderer .width )
@@ -230,6 +253,10 @@ def handle_resize(self, event):
230253 self ._png_is_old = True
231254 self .manager .resize (w , h )
232255
256+ def handle_send_image_mode (self , event ):
257+ # The client requests notification of what the current image mode is.
258+ self .send_event ('image_mode' , mode = self ._current_image_mode )
259+
233260 def send_event (self , event_type , ** kwargs ):
234261 self .manager ._send_event (event_type , ** kwargs )
235262
0 commit comments