Библиотека изображений Python - рендеринг текста - PullRequest
39 голосов
/ 24 марта 2011

Я пытаюсь визуализировать некоторый текст, используя PIL, но в результате получается, откровенно говоря, дерьмо.

Например, вот текст, который я написал в Photoshop:

PhotoShop

и что выходит из PIL:

PIL

Как вы видите, результаты PIL менее чем удовлетворительные. Может быть, я просто придирчив, но есть ли способ рисовать текст с помощью PIL, чтобы результаты были ближе к моему эталонному изображению?

Вот код, который я использую на Python 2.7 с PIL 1.1.7

image = Image.new("RGBA", (288,432), (255,255,255))
usr_font = ImageFont.truetype("resources/HelveticaNeueLight.ttf", 25)
d_usr = ImageDraw.Draw(image)
d_usr = d_usr.text((105,280), "Travis L.",(0,0,0), font=usr_font)

Ответы [ 5 ]

60 голосов
/ 25 марта 2011

Я придумал свое собственное решение, которое я считаю приемлемым.

Я сделал так, чтобы текст был сделан большим, например, в 3 раза больше его размера, а затем изменил его размер с помощью сглаживания, а не 100% идеально, но это чертовски лучше, чем по умолчанию, и не требует cairo или pango.

например,

image = Image.new("RGBA", (600,150), (255,255,255))
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("resources/HelveticaNeueLight.ttf", fontsize)

draw.text((10, 0), txt, (0,0,0), font=font)
img_resized = image.resize((188,45), Image.ANTIALIAS)

и вы в конечном итоге получите этот результат,

final result

, что намного лучше, чем то, что я получал раньше с тем же шрифтом.

20 голосов
/ 24 марта 2011

Попробуйте использовать pycairo - привязки python для библиотеки рисунков Cairo - это полезно для более тонкого рисования, с сглаженными линиями, и тому подобное - и вы можете создавать векторные изображения

Правильная обработка шрифтов, а разметка сложна и требует использования библиотеки "pango" и "pangocairo". Хотя они сделаны для серьезной работы со шрифтами (все виджеты GTK + используют pango для рендеринга шрифтов), доступные документы и примеры крайне скудны.

Образец ниже показывает распечатки, доступные в системе, и отображает образец текста в семействе шрифтов, переданный в качестве параметра в командной строке.

# -*- coding: utf-8 -*-
import cairo
import pango
import pangocairo
import sys

surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, 320, 120)
context = cairo.Context(surf)

#draw a background rectangle:
context.rectangle(0,0,320,120)
context.set_source_rgb(1, 1, 1)
context.fill()

#get font families:

font_map = pangocairo.cairo_font_map_get_default()
families = font_map.list_families()

# to see family names:
print [f.get_name() for f in   font_map.list_families()]

#context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)

# Positions drawing origin so that the text desired top-let corner is at 0,0
context.translate(50,25)

pangocairo_context = pangocairo.CairoContext(context)
pangocairo_context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)

layout = pangocairo_context.create_layout()
fontname = sys.argv[1] if len(sys.argv) >= 2 else "Sans"
font = pango.FontDescription(fontname + " 25")
layout.set_font_description(font)

layout.set_text(u"Travis L.")
context.set_source_rgb(0, 0, 0)
pangocairo_context.update_layout(layout)
pangocairo_context.show_layout(layout)

with open("cairo_text.png", "wb") as image_file:
    surf.write_to_png(image_file)

Rendred image

12 голосов
/ 24 марта 2011

Я никогда не использовал PIL, но быстрый просмотр документации по методу Draw показывает, что PIL предоставляет способ визуализации простой графики. Photoshop предоставляет способ визуализации сложной графики. Чтобы приблизиться к результатам, подобным Photoshop, требуется, как минимум, намеки на шрифты и сглаживание. Документация PIL даже не намекает на наличие таких возможностей. Возможно, вы захотите использовать внешний инструмент, который лучше справится с отображением текста на изображениях. Например, ImageMagick (вам нужно использовать 8-битную версию, которая обрабатывает стандартный 24-битный RGB). Вы можете найти некоторые образцы текстовых рисунков здесь: http://www.imagemagick.org/Usage/draw/

4 голосов
/ 30 ноября 2017

Предложение: используйте Wand или другую библиотеку изображений

Вот пример с палочкой -

from wand.color import Color
from wand.image import Image
from wand.drawing import Drawing
from wand.compat import nested

with Drawing() as draw:
    with Image(width=1000, height=100, background=Color('lightblue')) as img:
        draw.font_family = 'Indie Flower'
        draw.font_size = 40.0
        draw.push()
        draw.fill_color = Color('hsl(0%, 0%, 0%)')
        draw.text(0,int(img.height/2 + 20), 'Hello, world!')
        draw.pop()
        draw(img)
        img.save(filename='image.png')

image that comes out-

0 голосов
/ 01 ноября 2014

Вы также можете попытаться написать шрифт в два раза, что повышает качество.

image = Image.new("RGBA", (288,432), (255,255,255))
usr_font = ImageFont.truetype("resources/HelveticaNeueLight.ttf", 25)
d_usr = ImageDraw.Draw(image)
d_usr = d_usr.text((105,280), "Travis L.",(0,0,0), font=usr_font)
d_usr = d_usr.text((105,280), "Travis L.",(0,0,0), font=usr_font)
...