Как нарисовать текст под углом, используя PIL Python? - PullRequest
24 голосов
/ 29 октября 2008

Используя Python, я хочу иметь возможность рисовать текст под разными углами, используя PIL.

Например, представьте, что вы рисуете число вокруг циферблата часов. Число 3 будет выглядеть так, как ожидается, тогда как 12 будет нарисовано с поворотом против часовой стрелки на 90 градусов.

Поэтому мне нужно уметь рисовать много разных строк под разными углами.

Ответы [ 4 ]

38 голосов
/ 29 октября 2008

Нарисуйте текст во временное пустое изображение, поверните его, затем вставьте его на исходное изображение. Вы можете обернуть шаги в функции. Удачи в определении точных координат для использования - мой мозг в холодном тумане сейчас не до этого.

Это демо пишет желтый текст на наклонной поверх изображения:

# Demo to add rotated text to an image using PIL

import Image
import ImageFont, ImageDraw, ImageOps

im=Image.open("stormy100.jpg")

f = ImageFont.load_default()
txt=Image.new('L', (500,50))
d = ImageDraw.Draw(txt)
d.text( (0, 0), "Someplace Near Boulder",  font=f, fill=255)
w=txt.rotate(17.5,  expand=1)

im.paste( ImageOps.colorize(w, (0,0,0), (255,255,84)), (242,60),  w)
8 голосов
/ 12 апреля 2009

Также полезно знать размер нашего текста в пикселях, прежде чем мы создадим объект Image. Я использовал такой код при рисовании графиков. Тогда у меня нет проблем, например с выравниванием меток данных (изображение размером с текст).

(...)
img_main = Image.new("RGB", (200, 200))
font = ImageFont.load_default()

# Text to be rotated...
rotate_text = u'This text should be rotated.'

# Image for text to be rotated
img_txt = Image.new('L', font.getsize(rotate_text))
draw_txt = ImageDraw.Draw(img_txt)
draw_txt.text((0,0), rotate_text, font=font, fill=255)
t = img_value_axis.rotate(90, expand=1)

Остальное объединение двух изображений уже описано на этой странице. Когда вы поворачиваетесь на «нерегулярный» угол, вам нужно немного улучшить этот код. На самом деле работает на 90, 180, 270 ...

3 голосов
/ 29 октября 2008

Я не говорю, что это будет легко, или что это решение обязательно подойдет вам, но посмотрите документацию здесь:

http://effbot.org/imagingbook/pil-index.htm

и особенно обратите внимание на модули Image, ImageDraw и ImageFont.

Вот пример, который вам поможет:


import Image
im = Image.new("RGB", (100, 100))
import ImageDraw
draw = ImageDraw.Draw(im)
draw.text((50, 50), "hey")
im.rotate(45).show()

Чтобы сделать то, что вы действительно хотите, вам может понадобиться создать несколько отдельных правильно повернутых текстовых изображений, а затем скомпоновать их вместе с некоторыми более причудливыми манипуляциями. И после всего этого это все еще может не выглядеть великолепно. Я не уверен, как сглаживание и тому подобное обрабатываются, например, но это может быть не очень хорошо. Удачи, и если у кого-то есть более легкий путь, мне было бы интересно также узнать.

2 голосов
/ 23 февраля 2016

Вот рабочая версия, вдохновленная ответом, но она работает без открытия или сохранения изображений.

Два изображения имеют цветной фон и альфа-канал, отличный от нуля, чтобы показать, что происходит. Изменение двух альфа-каналов с 92 на 0 сделает их полностью прозрачными.

from PIL import Image, ImageFont, ImageDraw

text = 'TEST'
font = ImageFont.truetype(r'C:\Windows\Fonts\Arial.ttf', 50)
width, height = font.getsize(text)

image1 = Image.new('RGBA', (200, 150), (0, 128, 0, 92))
draw1 = ImageDraw.Draw(image1)
draw1.text((0, 0), text=text, font=font, fill=(255, 128, 0))

image2 = Image.new('RGBA', (width, height), (0, 0, 128, 92))
draw2 = ImageDraw.Draw(image2)
draw2.text((0, 0), text=text, font=font, fill=(0, 255, 128))

image2 = image2.rotate(30, expand=1)

px, py = 10, 10
sx, sy = image2.size
image1.paste(image2, (px, py, px + sx, py + sy), image2)

image1.show()
...