Библиотека изображений Python - визуализация текста

Я пытаюсь сделать какой-то текст с помощью 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)

Ответ 1

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

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

например,

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

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

Ответ 2

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

Правильная обработка шрифтов и макет сложны и требуют использования библиотеки "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

Ответ 3

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

Ответ 4

Предложение: используйте 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-

Ответ 5

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

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)