Любой способ сделать хорошие сглаженные круглые углы для изображений в Python? - PullRequest
14 голосов
/ 01 декабря 2009

Есть ли способ сделать красивые круглые углы с питоном? В настоящее время в моем проекте используются PIL и GD2. У обоих из них есть метод arc(), который позволяет нарисовать четверть круга, но четверть круга не сглажена, поэтому изображение выглядит хрустящим.

Есть ли какой-нибудь аккуратный способ сделать сглаженные / гладкие круглые углы?

Ответы [ 4 ]

16 голосов
/ 01 декабря 2009

Обычно я использую изображение в качестве маски, например, вот так:

border.png

альтернативный текст http://nadiana.com/sites/default/files/pil_tutorial/border.png

border = Image.open('border.png')
source = border.convert('RGB')
img.paste(source, mask=border)

Маска может быть изменена, чтобы соответствовать размерам, которые вы хотите. Просто убедитесь, что вы используете метод Image.ANTIALIAS.

Вы можете обратиться к учебному пособию Я написал некоторое время назад для получения более подробной информации (бесстыдный плагин)

Если вам нужен больший контроль над размером и радиусом, тогда вам нужно использовать дугу или фризель. Я не знаю как вы, но этот прямоугольник со скругленными углами, который я создал с помощью PIL, выглядит для меня достаточно гладким:

альтернативный текст http://nadiana.com/sites/default/files/round_rectangle.png

Вот код Я использовал его для рисования

Возможно, вам стоит проверить phatch: http://photobatch.wikidot.com/tutorials Он написан на Python и PIL и может накладывать круглые углы на фотографии.

alt text

Вот ссылка на код, используемый для наложения закругленных углов: http://bazaar.launchpad.net/~stani/phatch/trunk/annotate/head:/phatch/actions/round.py

Это также выглядит достаточно гладко для меня.

5 голосов
/ 01 декабря 2009

Вам потребуется суперсэмпл : нарисуйте дугу к большему изображению и уменьшите ее.

например. белая, гладкая полупрозрачная нижняя правая нижняя граница 16x16, с квадратным суперсэмплингом 4x4x:

>>> import Image, ImageDraw
>>> im= Image.new('RGBA', (16*4, 16*4), (255, 255, 255, 0))
>>> dr= ImageDraw.ImageDraw(im)
>>> dr.pieslice((-64, -64, 64, 64), 0, 340, fill=(255,255,255,255))
>>> im= im.resize((16, 16), Image.ANTIALIAS)
>>> im.save('border-se.png')
4 голосов
/ 03 декабря 2009

Итак, хорошо, я нашел решение.

Я использовал метод суперсэмплинга bobince , предложенный ранее, но обнаружил, что изображения становятся размытыми. Поэтому я бы не стал предоставлять полный код, но я объясню свое решение.

Это может показаться идиотским, но я не нашел другого способа сделать это без привлечения каких-либо других библиотек.

С помощью PIL вы рисуете на изображении белые (или любого другого цвета, включая прозрачные) углы. Затем вы копируете это. Теперь у вас должно быть два изображения с белыми круглыми углами без сглаживания.

Теперь вы должны использовать метод масштабирования -> суперсэмплинг (см. ответ Бобинса выше), чтобы сделать одно из изображений плавным (я использовал 8-кратное масштабирование).

Теперь у вас есть два изображения - одно с хрустящими углами, а другое с гладкими углами, но с размытым изображением.

Теперь вам нужно сделать углы на четком изображении прозрачными и вставить все изображение на гладкое. Для этого я использовал метод Image.composite (crispy_image, smooth_image, crispy_image) в библиотеке PIL.

Voila!

0 голосов
/ 01 сентября 2012

Используйте алгоритм окружности Сяолиня Ву, как описано в Graphics Gems II. Краткое резюме и пример (в php) можно найти здесь: http://create.stephan -brumme.com / antialiased-circle /

Что касается рисования дуги (частичной окружности), вы должны определить, находится ли данная точка в угловом диапазоне дуги, прежде чем наносить ее на карту.

...