39
39
from matplotlib .path import Path
40
40
from matplotlib .transforms import Bbox , BboxBase
41
41
from matplotlib import colors as mcolors
42
+ from matplotlib import image as mimage
42
43
43
44
from matplotlib .backends ._backend_agg import RendererAgg as _RendererAgg
44
45
from matplotlib import _png
@@ -514,7 +515,7 @@ def print_raw(self, filename_or_obj, *args, **kwargs):
514
515
if kwargs .get ('flatten' , False ):
515
516
w , h = int (renderer .width ), int (renderer .height )
516
517
img = np .array (memoryview (img )).reshape ((w , h , 4 ))
517
- img = self .flatten_rgba (img )
518
+ img = mimage .flatten_rgba (img )
518
519
519
520
try :
520
521
fileobj .write (img )
@@ -524,34 +525,6 @@ def print_raw(self, filename_or_obj, *args, **kwargs):
524
525
renderer .dpi = original_dpi
525
526
print_rgba = print_raw
526
527
527
- def flatten_rgba (self , src , bg = None ):
528
- """
529
- Flatten an RGBA image `src` with a background color `bg`.
530
- The resulting image will have an alpha channel, but no
531
- transparency. This is useful when interfacing with
532
- file formats that don't support transparency or only support
533
- boolean transparency.
534
- """
535
- if bg is None :
536
- bg = mcolors .colorConverter .to_rgb (
537
- rcParams .get ('savefig.facecolor' , 'white' ))
538
- bg = tuple ([int (x * 255.0 ) for x in bg ])
539
-
540
- # Numpy images have dtype=uint8 which will overflow
541
- src = src .astype (dtype = np .uint16 )
542
-
543
- alpha = src [:,:,3 ]
544
- src_rgb = src [:,:,:3 ]
545
- w , h , _ = src .shape
546
-
547
- result = np .empty ((w , h , 4 ))
548
- result [:,:,0 ] = (255 - alpha )* bg [0 ] + alpha * src_rgb [:,:,0 ]
549
- result [:,:,1 ] = (255 - alpha )* bg [1 ] + alpha * src_rgb [:,:,1 ]
550
- result [:,:,2 ] = (255 - alpha )* bg [2 ] + alpha * src_rgb [:,:,2 ]
551
- result = (result / 255 ).astype (np .uint8 )
552
- result [:,:,3 ] = 255
553
- return result
554
-
555
528
def print_png (self , filename_or_obj , * args , ** kwargs ):
556
529
FigureCanvasAgg .draw (self )
557
530
renderer = self .get_renderer ()
@@ -562,15 +535,18 @@ def print_png(self, filename_or_obj, *args, **kwargs):
562
535
close = True
563
536
else :
564
537
close = False
538
+
539
+ # Flatten RGBA if used as intermediate fileformat for something
540
+ # that doesn't support transparency (ie: Animations)
541
+ img = renderer ._renderer
542
+ if kwargs .get ('flatten' , False ):
543
+ img = img .buffer_rgba ()
544
+ w , h = int (renderer .width ), int (renderer .height )
545
+ img = renderer ._renderer .buffer_rgba ()
546
+ img = np .array (memoryview (img )).reshape ((h , w , 4 ))
547
+ img = mimage .flatten_rgba (img )
565
548
try :
566
- if kwargs .get ('flatten' , False ):
567
- w , h = int (renderer .width ), int (renderer .height )
568
- img = renderer ._renderer .buffer_rgba ()
569
- img = np .array (memoryview (img )).reshape ((h ,w ,4 ))
570
- img = self .flatten_rgba (img )
571
- _png .write_png (img , filename_or_obj , self .figure .dpi )
572
- else :
573
- _png .write_png (renderer ._renderer , filename_or_obj , self .figure .dpi )
549
+ _png .write_png (img , filename_or_obj , self .figure .dpi )
574
550
finally :
575
551
if close :
576
552
filename_or_obj .close ()
@@ -605,24 +581,22 @@ def print_jpg(self, filename_or_obj, *args, **kwargs):
605
581
*progressive*: If present, indicates that this image
606
582
should be stored as a progressive JPEG file.
607
583
"""
608
- buf , size = self .print_to_buffer ()
584
+ buf , (w , h ) = self .print_to_buffer ()
585
+ buf = np .array (memoryview (buf )).reshape ((w , h , 4 ))
586
+
609
587
if kwargs .pop ("dryrun" , False ):
610
588
return
611
589
# The image is "pasted" onto a white background image to safely
612
590
# handle any transparency
613
- image = Image .frombuffer ('RGBA' , size , buf , 'raw' , 'RGBA' , 0 , 1 )
614
- color = mcolors .colorConverter .to_rgb (
615
- rcParams .get ('savefig.facecolor' , 'white' ))
616
- color = tuple ([int (x * 255.0 ) for x in color ])
617
- background = Image .new ('RGB' , size , color )
618
- background .paste (image , image )
591
+ buf = mimage .flatten_rgba (buf )
592
+ img = Image .frombuffer ('RGBA' , (w , h ), buf , 'raw' , 'RGBA' , 0 , 1 )
593
+
619
594
options = restrict_dict (kwargs , ['quality' , 'optimize' ,
620
595
'progressive' ])
621
-
622
596
if 'quality' not in options :
623
597
options ['quality' ] = rcParams ['savefig.jpeg_quality' ]
624
598
625
- return background .save (filename_or_obj , format = 'jpeg' , ** options )
599
+ return img .save (filename_or_obj , format = 'jpeg' , ** options )
626
600
print_jpeg = print_jpg
627
601
628
602
# add TIFF support
0 commit comments