47
47
from matplotlib .font_manager import ttfFontProperty
48
48
49
49
50
+ def _premultiplied_argb32_to_unmultiplied_rgba8888 (buf ):
51
+ """
52
+ Convert a premultiplied ARGB32 buffer to an unmultiplied RGBA8888 buffer.
53
+
54
+ Cairo uses the former format, Matplotlib the latter.
55
+ """
56
+ rgba = np .take ( # .take() ensures C-contiguity of the result.
57
+ buf ,
58
+ [2 , 1 , 0 , 3 ] if sys .byteorder == "little" else [1 , 2 , 3 , 0 ], axis = 2 )
59
+ rgb = rgba [..., :- 1 ]
60
+ alpha = rgba [..., - 1 ]
61
+ # Un-premultiply alpha. The formula is the same as in cairo-png.c.
62
+ mask = alpha != 0
63
+ for channel in np .rollaxis (rgb , - 1 ):
64
+ channel [mask ] = (
65
+ (channel [mask ].astype (int ) * 255 + alpha [mask ] // 2 )
66
+ // alpha [mask ])
67
+ return rgba
68
+
69
+
50
70
class ArrayWrapper :
51
71
"""Thin wrapper around numpy ndarray to expose the interface
52
72
expected by cairocffi. Basically replicates the
@@ -436,15 +456,24 @@ class FigureCanvasCairo(FigureCanvasBase):
436
456
supports_blit = False
437
457
438
458
def print_png (self , fobj , * args , ** kwargs ):
459
+ self ._get_printed_image_surface ().write_to_png (fobj )
460
+
461
+ def print_rgba (self , fobj , * args , ** kwargs ):
439
462
width , height = self .get_width_height ()
463
+ buf = self ._get_printed_image_surface ().get_data ()
464
+ fobj .write (_premultiplied_argb32_to_unmultiplied_rgba8888 (
465
+ np .asarray (buf ).reshape ((width , height , 4 ))))
466
+
467
+ print_raw = print_rgba
440
468
469
+ def _get_printed_image_surface (self ):
470
+ width , height = self .get_width_height ()
441
471
renderer = RendererCairo (self .figure .dpi )
442
472
renderer .set_width_height (width , height )
443
473
surface = cairo .ImageSurface (cairo .FORMAT_ARGB32 , width , height )
444
474
renderer .set_ctx_from_surface (surface )
445
-
446
475
self .figure .draw (renderer )
447
- surface . write_to_png ( fobj )
476
+ return surface
448
477
449
478
def print_pdf (self , fobj , * args , ** kwargs ):
450
479
return self ._save (fobj , 'pdf' , * args , ** kwargs )
0 commit comments