@@ -65,6 +65,12 @@ def __init__(self, *args, **kwargs):
65
65
# sent to the clients will be a full frame.
66
66
self ._force_full = True
67
67
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
+
68
74
def show (self ):
69
75
# show the figure window
70
76
from matplotlib .pyplot import show
@@ -86,24 +92,41 @@ def draw(self):
86
92
def draw_idle (self ):
87
93
self .send_event ("draw" )
88
94
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
+
89
111
def get_diff_image (self ):
90
112
if self ._png_is_old :
113
+ renderer = self .get_renderer ()
114
+
91
115
# The buffer is created as type uint32 so that entire
92
116
# pixels can be compared in one numpy call, rather than
93
117
# needing to compare each plane separately.
94
- renderer = self .get_renderer ()
95
118
buff = np .frombuffer (renderer .buffer_rgba (), dtype = np .uint32 )
96
-
97
119
buff .shape = (renderer .height , renderer .width )
98
120
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.
101
123
pixels = buff .view (dtype = np .uint8 ).reshape (buff .shape + (4 ,))
102
- some_transparency = np .any (pixels [:, :, 3 ] != 255 )
103
-
104
- output = buff
105
124
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' )
107
130
last_buffer = np .frombuffer (self ._last_renderer .buffer_rgba (),
108
131
dtype = np .uint32 )
109
132
last_buffer .shape = (renderer .height , renderer .width )
@@ -230,6 +253,10 @@ def handle_resize(self, event):
230
253
self ._png_is_old = True
231
254
self .manager .resize (w , h )
232
255
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
+
233
260
def send_event (self , event_type , ** kwargs ):
234
261
self .manager ._send_event (event_type , ** kwargs )
235
262
0 commit comments