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

时间:2021-08-10 00:25:15

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

我正在webserver上使用sorl-thumbnail、PIL和Django在模板中动态创建缩略图。

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.

PIL安装了PNG支持,但是出于某种原因,转换在图像的透明部分创建了一些非常奇怪的工件。

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

我使用Github上的这个要点来安装所需的依赖项:https://raw.github.com/gist/1225180/eb87ceaa72778f17f17f76a89a066101ba2254391/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

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

After

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

3 个解决方案

#1


24  

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

看起来您的结果映像是一个JPEG。JPEG格式不支持透明性。试着改变你的缩略图模板:

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

#2


6  

Either:

:

  • add format='PNG'.
  • 添加=的PNG格式。
  • add THUMBNAIL_PRESERVE_FORMAT=True to the settings.
  • 为设置添加THUMBNAIL_PRESERVE_FORMAT=True。
  • or use the custom engine as described here:
  • 或者使用这里描述的自定义引擎:

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

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 %}

#3


1  

I'd suggest you rather look into how sorl's PIL backend handles scaling. I imagine it creates some helper image to apply additional effects on and then tells PIL to scale the original onto that. You need to make sure that the destination is using the RGBA mode to support transparency and that it starts with its alpha set to zero (and not pure white or pitch black or something similar). If your image is using an indexed palette then it's possible it does not get converted to RGBA. In indexed mode PNGs store the transparent color index in their metadata but the process of creating the thumbnail will alter pixels due to antialiasing so you cannot preserve indexed transparency in:

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

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

#1


24  

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

看起来您的结果映像是一个JPEG。JPEG格式不支持透明性。试着改变你的缩略图模板:

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

#2


6  

Either:

:

  • add format='PNG'.
  • 添加=的PNG格式。
  • add THUMBNAIL_PRESERVE_FORMAT=True to the settings.
  • 为设置添加THUMBNAIL_PRESERVE_FORMAT=True。
  • or use the custom engine as described here:
  • 或者使用这里描述的自定义引擎:

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

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 %}

#3


1  

I'd suggest you rather look into how sorl's PIL backend handles scaling. I imagine it creates some helper image to apply additional effects on and then tells PIL to scale the original onto that. You need to make sure that the destination is using the RGBA mode to support transparency and that it starts with its alpha set to zero (and not pure white or pitch black or something similar). If your image is using an indexed palette then it's possible it does not get converted to RGBA. In indexed mode PNGs store the transparent color index in their metadata but the process of creating the thumbnail will alter pixels due to antialiasing so you cannot preserve indexed transparency in:

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

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