Как нарисовать текст под углом, используя PIL Python?

StackOverflow https://stackoverflow.com/questions/245447

Вопрос

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

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

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

Это было полезно?

Решение

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

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

# 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)

Другие советы

Также полезно знать размер нашего текста в пикселях, прежде чем мы создадим объект 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 ...

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

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()

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

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

Два изображения имеют цветной фон и альфа-канал, отличный от нуля, чтобы показать, что происходит. Изменение двух альфа-каналов с 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()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top