Прозрачные PNG не сохраняют прозрачность после преобразования (Django + PIL) - PullRequest
11 голосов
/ 27 сентября 2011

Я использую sorl-thumbnail , PIL и Django на веб-сервере для динамического создания миниатюр в шаблонах.

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 ]

25 голосов
/ 27 сентября 2011

Похоже, ваше полученное изображение в формате JPEG.Формат JPEG не поддерживает прозрачность.Попробуйте изменить шаблон миниатюры на это:

{% thumbnail project.image "148x108" crop="center" format="PNG" as im %}
6 голосов
/ 18 сентября 2014

Или:

  • добавить 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 %}
1 голос
/ 27 сентября 2011

Я бы посоветовал вам посмотреть, как PIL-сервер sorl справляется с масштабированием. Я предполагаю, что он создает какое-то вспомогательное изображение для применения дополнительных эффектов, а затем говорит PIL масштабировать оригинал на это. Вы должны убедиться, что пункт назначения использует режим RGBA для поддержки прозрачности и что он начинается с его альфа-канала, установленного на ноль (а не чисто белый или абсолютно черный или что-то подобное). Если ваше изображение использует индексированную палитру, возможно, оно не преобразуется в RGBA. В индексированном режиме PNG хранят индекс прозрачного цвета в своих метаданных, но процесс создания эскиза изменит пиксели из-за сглаживания, поэтому вы не сможете сохранить индексированную прозрачность в:

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