Завернуть текст в ПИЛ - PullRequest
       16

Завернуть текст в ПИЛ

12 голосов
/ 24 ноября 2011

Я использую PIL для рисования текста на изображении. Как бы я обернуть строку текста. Это мой код:

text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

image = Image.open("/tmp/background-image.jpg")
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"), 50, encoding='unic')
draw.text((100, 100), text, font=font, fill="#aa0000")
image.save("/tmp/image.jpg")

Ответы [ 4 ]

12 голосов
/ 25 ноября 2011

Вам нужно будет сначала разбить текст на строки правильной длины, а затем нарисовать каждую линию по отдельности.

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

margin = offset = 40
for line in textwrap.wrap(text, width=40):
    draw.text((margin, offset), line, font=font, fill="#aa0000")
    offset += font.getsize(line)[1]
5 голосов
/ 24 ноября 2011

Ну, конечно, вы можете сделать это вручную, используя \ n каждый раз, когда хотите обернуть текст. Это не лучший способ, если у вас всегда разные строки, но вы полностью контролируете результат. Но есть также модуль textwrap. Вы можете использовать это следующим образом:

import textwrap
texto = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
novo = textwrap.wrap(texto, width=20)
print(novo)

Результаты:

>>> 
['Lorem ipsum dolor', 'sit amet,', 'consectetur', 'adipisicing elit,', 'sed do eiusmod', 'tempor incididunt ut', 'labore et dolore', 'magna aliqua. Ut', 'enim ad minim', 'veniam, quis nostrud', 'exercitation ullamco', 'laboris nisi ut', 'aliquip ex ea', 'commodo consequat.', 'Duis aute irure', 'dolor in', 'reprehenderit in', 'voluptate velit esse', 'cillum dolore eu', 'fugiat nulla', 'pariatur. Excepteur', 'sint occaecat', 'cupidatat non', 'proident, sunt in', 'culpa qui officia', 'deserunt mollit anim', 'id est laborum.']

Возвращает список терминов в предыдущей строке, перенесенный в соответствии с определенной вами шириной.

2 голосов
/ 15 сентября 2017

Допустимый перенос текста, основанный на фиксированном ограничении в 40 символов на строку, без учета ширины поля (в пикселях) или размера шрифта.Это может легко привести к недостаточному или переполнению.

Вот лучшее решение - простой фрагмент кода для обработки переноса текста с использованием измерения ширины на основе шрифта: https://gist.github.com/turicas/1455973

0 голосов
/ 06 марта 2019

Это работает для меня.С типографской точки зрения было бы неплохо добавить больше операторов, например, проверить, разбито ли слово на середину, поставить дефис, проверить, присутствуют ли по крайней мере 2 буквы в начале и конце слова.Я обязательно посмотрю его позже.

content_raw = 'AND WHAT ABOUT SOMETHING VERY LONG'
content = ''
for i in content_raw:
    if draw.textsize(content.split('\n')[-1])[0] > 30:
        content += '\n'
    content += i
...