@@ -1515,18 +1515,37 @@ def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None,
15151515 origin = mpl .rcParams ["image.origin" ]
15161516 if origin == "lower" :
15171517 arr = arr [::- 1 ]
1518- rgba = sm .to_rgba (arr , bytes = True )
1518+ if (isinstance (arr , memoryview ) and arr .format == "B"
1519+ and arr .ndim == 3 and arr .shape [- 1 ] == 4 ):
1520+ # Such an ``arr`` would also be handled fine by sm.to_rgba (after
1521+ # casting with asarray), but it is useful to special-case it
1522+ # because that's what backend_agg passes, and can be in fact used
1523+ # as is, saving a few operations.
1524+ rgba = arr
1525+ else :
1526+ rgba = sm .to_rgba (arr , bytes = True )
15191527 if pil_kwargs is None :
15201528 pil_kwargs = {}
15211529 pil_shape = (rgba .shape [1 ], rgba .shape [0 ])
15221530 image = PIL .Image .frombuffer (
15231531 "RGBA" , pil_shape , rgba , "raw" , "RGBA" , 0 , 1 )
1524- if format == "png" and metadata is not None :
1525- # cf. backend_agg's print_png.
1526- pnginfo = PIL .PngImagePlugin .PngInfo ()
1527- for k , v in metadata .items ():
1528- pnginfo .add_text (k , v )
1529- pil_kwargs ["pnginfo" ] = pnginfo
1532+ if format == "png" :
1533+ # Only use the metadata kwarg if pnginfo is not set, because the
1534+ # semantics of duplicate keys in pnginfo is unclear.
1535+ if "pnginfo" in pil_kwargs :
1536+ if metadata :
1537+ cbook ._warn_external ("'metadata' is overridden by the "
1538+ "'pnginfo' entry in 'pil_kwargs'." )
1539+ else :
1540+ metadata = {
1541+ "Software" : (f"Matplotlib version{ mpl .__version__ } , "
1542+ f"https://matplotlib.org/" ),
1543+ ** (metadata if metadata is not None else {}),
1544+ }
1545+ pil_kwargs ["pnginfo" ] = pnginfo = PIL .PngImagePlugin .PngInfo ()
1546+ for k , v in metadata .items ():
1547+ if v is not None :
1548+ pnginfo .add_text (k , v )
15301549 if format in ["jpg" , "jpeg" ]:
15311550 format = "jpeg" # Pillow doesn't recognize "jpg".
15321551 facecolor = mpl .rcParams ["savefig.facecolor" ]
0 commit comments