Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transparent PNGs don't retain transparency after being transformed (Django + PIL)

I'm using sorl-thumbnail, PIL, and Django on a webserver to dynamically create thumbnails in templates.

PIL is installed with PNG support, but for some reason the transformations are creating some really bizarre artifacts on the transparent portions of the images.

I used this gist on Github to install the required dependencies: https://raw.github.com/gist/1225180/eb87ceaa7277078f17f76a89a066101ba2254391/patch.sh

Here is the template code that generates the images (I don't think this is where the problem is, but can't hurt to show you):

{% thumbnail project.image "148x108" crop="center" as im %}
  <img src='{{ im.url }}' />
{% endthumbnail %}

Below is an example of what happens. Any help is greatly appreciated!

Before

Image with transparency

After

Image with artifacts

like image 577
dwlz Avatar asked Sep 26 '11 21:09

dwlz


2 Answers

It looks like your resulting image is a JPEG. The JPEG format does not support transparency. Try changing your thumbnail template to this:

{% thumbnail project.image "148x108" crop="center" format="PNG" as im %}
like image 142
jterrace Avatar answered Nov 16 '22 01:11

jterrace


Either:

  • add format='PNG'.
  • add THUMBNAIL_PRESERVE_FORMAT=True to the settings.
  • or use the custom engine as described here:

http://yuji.wordpress.com/2012/02/26/sorl-thumbnail-convert-png-to-jpeg-with-background-color/

"""
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

in your settings:

THUMBNAIL_ENGINE = 'path.to.Engine'

You can use the option now:

{% thumbnail my_file "100x100" format="JPEG" background="#333333" as thumb %}
   <img src="{{ thumb.url }}" />
{% endthumbnail %}
like image 44
vdboor Avatar answered Nov 16 '22 00:11

vdboor