Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PIL: can't save the jpg pasted with a png

I'm trying to paste a png on a jpg. Here is the code:

#!/usr/bin/env python3

from PIL import Image
from PIL import ImageDraw

im = Image.open("existing.jpg")
logo = Image.open("python-32.png")

back = Image.new('RGBA', im.size)
back.paste(im)
poly = Image.new('RGBA', (512,512))
pdraw = ImageDraw.Draw(poly)
pdraw.polygon([(128,128),(384,384),(128,384),(384,128)],
          fill=(255,255,255,127),outline=(255,255,255,255))

back.paste(poly, (0,0), mask=poly)
back.paste(logo, (im.size[0]-logo.size[0], im.size[1]-logo.size[1]), mask=logo)

back.show()

When I execute the code above, I can see that a PNG image is shown with a random name like tmpc8rb455z.PNG.

I also try to save it with the format jpg but failed. Meaning that when I add back.save('res.jpg', 'JPEG') and execute it, I get such an error:

Traceback (most recent call last):
  File "test.py", line 32, in <module>
    back.save('res.jpg', 'JPEG')
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/PIL/Image.py", line 1893, in save
    save_handler(self, fp, filename)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/PIL/JpegImagePlugin.py", line 604, in _save
    raise IOError("cannot write mode %s as JPEG" % im.mode)
OSError: cannot write mode RGBA as JPEG

Then I try to save it as PNG:
back.save('res.png')

It works but the size of res.png is 5 times larger than existing.jpg. I can not accept such a huge image.

like image 804
Yves Avatar asked Dec 24 '22 15:12

Yves


1 Answers

You're attempting to save an RGBA image in the JPEG format, which does not support transparency (A in RGBA stands for Alpha channel).

It works when you save it as a PNG, because that format supports transparency, but the file size tends to be larger because PNG doesn't compress image data as much as JPEG.

If you want to save PIL images as JPEG, you will need to first convert it to RGB, if transparency isn't important to you. This can be done as follows:

im = im.convert("RGB")

like image 191
JoshuaRLi Avatar answered Dec 29 '22 11:12

JoshuaRLi