透明PNG经过转换后不保留透明度(Django + PIL)

11 投票
3 回答
5390 浏览
提问于 2025-04-17 03:08

我在一个网络服务器上使用了 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 %}

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

处理前

带透明部分的图片

处理后

带奇怪现象的图片

3 个回答

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')
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 %}
25

看起来你得到的图片是JPEG格式的。JPEG格式不支持透明背景。试着把你的缩略图模板改成这样:

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

撰写回答