透明PNG在转换后不保持透明度(Django + PIL)

时间:2011-09-26 21:56:05

标签: python django python-imaging-library

我在网络服务器上使用sorl-thumbnailPILDjango来动态创建模板中的缩略图。

PIL安装时支持PNG,但由于某种原因,转换会在图像的透明部分上创建一些非常奇怪的瑕疵。

我在Github上使用这个要点来安装所需的依赖项:https://raw.github.com/gist/1225180/eb87ceaa7277078f17f76a89a066101ba2254391/patch.sh

以下是生成图像的模板代码(我不认为这是问题所在,但不能向您展示):

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

以下是所发生情况的示例。非常感谢任何帮助!

之前

Image with transparency

Image with artifacts

3 个答案:

答案 0 :(得分:25)

看起来你的结果图像是JPEG。 JPEG格式不支持透明度。尝试将缩略图模板更改为:

{% thumbnail project.image "148x108" crop="center" format="PNG" as im %}

答案 1 :(得分:6)

或者:

  • 添加format='PNG'
  • THUMBNAIL_PRESERVE_FORMAT=True添加到设置中。
  • 或使用此处所述的自定义引擎:

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

在您的设置中:

THUMBNAIL_ENGINE = 'path.to.Engine'

您现在可以使用该选项:

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

答案 2 :(得分:1)

我建议你去研究一下sorl的PIL后端如何处理扩展。我想它会创建一些辅助图像以应用其他效果,然后告诉PIL将原始图像缩放到其上。您需要确保目标正在使用RGBA模式来支持透明度,并且它的alpha设置为零(而不是纯白色或黑色或类似的东西)。如果您的图像使用索引调色板,那么它可能无法转换为RGBA。在索引模式下,PNG将透明颜色索引存储在其元数据中,但创建缩略图的过程将因抗锯齿而改变像素,因此您无法在以下位置保留索引透明度:

source = Image.open('dead-parrot.png')
source.convert('RGBA')
dest = source.resize((100, 100), resample=Image.ANTIALIAS)
dest.save('ex-parrot.png')