Прозрачное изменение размера png с помощью библиотеки изображений Python и эффекта ореола - PullRequest
5 голосов
/ 04 февраля 2012

Есть пара похожих вопросов по SO, но ни один из них действительно не помог. В основном я пытаюсь изменить размер простого изображения PNG, как показано здесь:

http://media.spiralknights.com/wiki-images/3/3e/Equipment-Proto_Sword_icon.png (от mmo Spiral Knights, авторское право Three Rings Entertainment)

Первоначально я внедрил утилиту, которая использует эти изображения в php, и утилита изменения размера работала там отлично. Я использовал метод, описанный на странице imagecopyresampled в документации PHP.

Честно говоря, я даже не могу заставить его изменить размер в Photoshop, но в python результаты почти катастрофические. Я последовательно получаю эффект ореола, и я полагаю, что это по крайней мере частично соответствует фактическим значениям RGBA прозрачных пикселей. Здесь эта картина говорит лучше:

resize examples

(изменение размера от второго до последнего было всего лишь предложением, которое я видел на другом форуме, о том, чтобы изменить размер с первого до двойного размера, и это ДЕЙСТВИТЕЛЬНО помогло хотя бы немного, но недостаточно)

Изображение уже находится в режиме RGBA, когда оно изменяется.

Как видите, изменения в PHP и Photoshop не требуют ореолов. Честно говоря, все, кроме изменения размера PHP, делает СЛИШКОМ большую работу, мне нравится минимальная палитра в изображении php (если вы посмотрите на более крупные версии, вы увидите, что изменение размера PHP использует меньше между цветами), но я мог бы жить с тем, как Photoshop изменил его размер, или даже изменил размер внутренней части питона, но ореол недопустим.

Мне кажется - и поправьте меня, если я ошибаюсь - что PHP и Photoshop, кажется, знают, что не используют цвет пикселей в альфа-канале при интерполяции, но python использует эту светлую границу, которая в остальном прозрачен в своем размере.

К сожалению, есть много разных значков, которые мне нужно изменить, с разными профилями, поэтому они не так просты, как этот круглый, но это был только первый, который я использовал во время экспериментов.

Сам по себе вопрос кода не так уж и велик, но если вам нужно что-то посмотреть, вот суть:

>> import Image
>> img = Image.open('swordorig.png')
>> img
<PngImagePlugin.PngImageFile image mode=RGBA size=256x256 at 0x2A3AF58>
>> img.resize((36,36), Image.ANTIALIAS).save('swordresize.png')

В конечном итоге возникает вопрос: есть ли способ указать PIL NOT использовать цвет пикселя с альфа-значением 0 при повторной дискретизации?

1 Ответ

6 голосов
/ 05 февраля 2012

Спасибо всем за ответы!И особенно к rotoglup за то, что он сказал мне термин для того, что я действительно искал.Просматривая страницы переполнения стека для предварительно умноженной альфы в PIL, я нашел решение, которое работает;Вот обновленный лист графики изменения размера:

resize sheet 2

Серые полосы просто для того, чтобы создать впечатление, как они будут выглядеть на светлом фоне.

https://stackoverflow.com/a/6882161/1189554

Благодаря madlag

Итак, мой код выглядит примерно так:

>> import Image, numpy
>> img = Image.open('swordorig.png')
>> premult = numpy.fromstring(img.tostring(), dtype=numpy.uint8)
>> alphaLayer = premult[3::4] / 255.0
>> premult[::4] *= alphaLayer
>> premult[1::4] *= alphaLayer
>> premult[2::4] *= alphaLayer
>> img = Image.fromstring("RGBA", img.size, premult.tostring())
>> img.resize((36,36), Image.ANTIALIAS).save('swordresize.png')

И вы получаете значок, который находится внизу листа.Все еще больше цветов, чем версия PHP, и очень мягкое звучание, но в целом намного, намного приятнее.Я уверен, что алгоритм может быть улучшен, чтобы улучшить его еще больше.Еще раз спасибо всем за ответы!

...