42
42
from matplotlib .transforms import Affine2D
43
43
44
44
45
+ # Cairo's image buffers are premultiplied ARGB32,
46
+ # Matplotlib's are unmultiplied RGBA8888.
47
+
48
+
45
49
def _premultiplied_argb32_to_unmultiplied_rgba8888 (buf ):
46
50
"""
47
51
Convert a premultiplied ARGB32 buffer to an unmultiplied RGBA8888 buffer.
48
-
49
- Cairo uses the former format, Matplotlib the latter.
50
52
"""
51
53
rgba = np .take ( # .take() ensures C-contiguity of the result.
52
54
buf ,
@@ -62,6 +64,26 @@ def _premultiplied_argb32_to_unmultiplied_rgba8888(buf):
62
64
return rgba
63
65
64
66
67
+ def _unmultipled_rgba8888_to_premultiplied_argb32 (rgba8888 ):
68
+ """
69
+ Convert an unmultiplied RGBA8888 buffer to a premultiplied ARGB32 buffer.
70
+ """
71
+ if sys .byteorder == "little" :
72
+ argb32 = np .take (rgba8888 , [2 , 1 , 0 , 3 ], axis = 2 )
73
+ rgb24 = argb32 [..., :- 1 ]
74
+ alpha8 = argb32 [..., - 1 :]
75
+ else :
76
+ argb32 = np .take (rgba8888 , [3 , 0 , 1 , 2 ], axis = 2 )
77
+ alpha8 = argb32 [..., :1 ]
78
+ rgb24 = argb32 [..., 1 :]
79
+ # Only bother premultiplying when the alpha channel is not fully opaque,
80
+ # as the cost is not negligible. The unsafe cast is needed to do the
81
+ # multiplication in-place in an integer buffer.
82
+ if alpha8 .min () != 0xff :
83
+ np .multiply (rgb24 , alpha8 / 0xff , out = rgb24 , casting = "unsafe" )
84
+ return argb32
85
+
86
+
65
87
if cairo .__name__ == "cairocffi" :
66
88
# Convert a pycairo context to a cairocffi one.
67
89
def _to_context (ctx ):
@@ -358,11 +380,7 @@ def _draw_paths():
358
380
_draw_paths ()
359
381
360
382
def draw_image (self , gc , x , y , im ):
361
- # bbox - not currently used
362
- if sys .byteorder == 'little' :
363
- im = im [:, :, (2 , 1 , 0 , 3 )]
364
- else :
365
- im = im [:, :, (3 , 0 , 1 , 2 )]
383
+ im = _unmultipled_rgba8888_to_premultiplied_argb32 (im [::- 1 ])
366
384
surface = cairo .ImageSurface .create_for_data (
367
385
im .ravel ().data , cairo .FORMAT_ARGB32 ,
368
386
im .shape [1 ], im .shape [0 ], im .shape [1 ] * 4 )
@@ -371,10 +389,7 @@ def draw_image(self, gc, x, y, im):
371
389
372
390
ctx .save ()
373
391
ctx .set_source_surface (surface , float (x ), float (y ))
374
- if gc .get_alpha () != 1 :
375
- ctx .paint_with_alpha (gc .get_alpha ())
376
- else :
377
- ctx .paint ()
392
+ ctx .paint ()
378
393
ctx .restore ()
379
394
380
395
def draw_text (self , gc , x , y , s , prop , angle , ismath = False , mtext = None ):
0 commit comments