Sorl Thumbnail Convert PNG to JPEG with Background Color

The benefits of PNGs are obvious: it’s lossless and it supports transparency (alpha).

Unfortunately, that means these files are humongous. As PNGs get more complex, every pixel gets recorded so a product shot might be 1000KB as PNG, and 50KB as a JPEG looking not all that much worse.

If you try to convert a PNG to a JPEG via Sorl thumbnail library, it will by default use a white background, and for some reason causes artifacting as well on partial alphas such as shadows.

Ideally, we have a super high quality PNG that can be converted and optimized to a JPG on the fly, so I created a PIL sorl thumbnail engine that accepts a new template tag argument: “background” – which is an RGB color that will be applied as the background color to an RGBA image source.

Apparently, my solution is the simplest, and fastest of the RGBA->JPG methods described at this stack overflow question.

The Code: Converting Transparent PNGs to JPEGs with Background Colors

"""
Sorl Thumbnail Engine that accepts background color
---------------------------------------------------

Created on Sunday, February 2012 by Yuji Tomita
"""
from PIL import Image, ImageColor
from sorl.thumbnail.engines.pil_engine import Engine


class Engine(Engine):
	def create(self, image, geometry, options):
		thumb = super(Engine, self).create(image, geometry, options)
		if options.get('background'):		
			try:
				background = Image.new('RGB', thumb.size, ImageColor.getcolor(options.get('background'), 'RGB'))
				background.paste(thumb, mask=thumb.split()[3]) # 3 is the alpha of an RGBA image.
				return background
			except Exception, e:
				return thumb
		return thumb

Now, just modify your thumbnail engine setting

THUMBNAIL_ENGINE = 'path.to.Engine'

Usage

{% thumbnail my_file "100x100" format="JPEG" background="#333333" as thumb %}
   <img src="{{ thumb.url }}" />
{% endthumbnail %}

Done!

Conclusion

Now, we can store/upload one copy of a perfect PNG and have the website automatically generate an optimized JPEG regardless of the situation. Seriously amazing.

Need a smaller PNG? done.
Need a smaller JPEG with background color black? done.

https://gist.github.com/1920535