Skip to content

Commit bdea63d

Browse files
committed
Fix #5302: Proper alpha-blending for jpeg
1 parent 634c4bf commit bdea63d

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

lib/matplotlib/backends/backend_agg.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,6 @@ def print_to_buffer(self):
551551
return result
552552

553553
if _has_pil:
554-
555554
# add JPEG support
556555
def print_jpg(self, filename_or_obj, *args, **kwargs):
557556
"""
@@ -573,14 +572,18 @@ def print_jpg(self, filename_or_obj, *args, **kwargs):
573572
buf, size = self.print_to_buffer()
574573
if kwargs.pop("dryrun", False):
575574
return
575+
# The image is "pasted" onto a white background image to safely
576+
# handle any transparency
576577
image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
578+
background = Image.new('RGB', size, (255, 255, 255))
579+
background.paste(image, image)
577580
options = restrict_dict(kwargs, ['quality', 'optimize',
578581
'progressive'])
579582

580583
if 'quality' not in options:
581584
options['quality'] = rcParams['savefig.jpeg_quality']
582585

583-
return image.save(filename_or_obj, format='jpeg', **options)
586+
return background.save(filename_or_obj, format='jpeg', **options)
584587
print_jpeg = print_jpg
585588

586589
# add TIFF support

lib/matplotlib/tests/test_image.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,28 @@ def test_nonuniformimage_setnorm():
453453
im = NonUniformImage(ax)
454454
im.set_norm(plt.Normalize())
455455

456+
@knownfailureif(not HAS_PIL)
457+
@cleanup
458+
def test_jpeg_alpha():
459+
plt.figure(figsize=(1, 1), dpi=300)
460+
# Create an image that is all black, with a gradient from 0-1 in
461+
# the alpha channel from left to right.
462+
im = np.zeros((300, 300, 4), dtype=np.float)
463+
im[..., 3] = np.linspace(0.0, 1.0, 300)
464+
465+
plt.figimage(im)
466+
467+
buff = io.BytesIO()
468+
plt.savefig(buff, transparent=True, format='jpg', dpi=300)
469+
470+
buff.seek(0)
471+
image = Image.open(buff)
472+
473+
# If this fails, there will be only one color (all black). If this
474+
# is working, we should have all 256 shades of grey represented.
475+
assert len(image.getcolors(256)) == 256
476+
477+
456478
if __name__=='__main__':
457479
import nose
458480
nose.runmodule(argv=['-s','--with-doctest'], exit=False)

0 commit comments

Comments
 (0)