Python 图像库 - 文本渲染

问题描述 投票:0回答:7

我正在尝试使用 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)
python python-imaging-library imaging
7个回答
69
投票

我提出了自己认为可以接受的解决方案。

我所做的是将文本渲染得很大,比如需要的大小的 3 倍,然后缩放并使用抗锯齿功能缩小它的大小,它不是 100% 完美,但它比默认值要好得多,并且不需要 cairo或潘戈。

例如,

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

这比我之前使用相同字体得到的要好得多。


22
投票

尝试使用 pycairo - Cairo 绘图库的 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


12
投票

我从未使用过 PIL,但快速浏览一下 Draw 方法的文档表明 PIL 提供了一种渲染“简单”图形的方法。 Photoshop 提供了一种渲染“复杂”图形的方法。要获得接近 Photoshop 的效果,至少需要字体提示和抗锯齿功能。 PIL 的文档甚至没有暗示具有此类功能。您可能想考虑使用外部工具,它可以更好地在图像上渲染文本。例如,ImageMagick(您需要使用 8 位版本,它处理标准 24 位 RGB)。您可以在这里找到一些文本绘制示例:http://www.imagemagick.org/Usage/draw/ 建议:使用 Wand 或其他成像库


7
投票

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

在 python3 中,有一个别名字体的选项。我在任何地方都找不到这个答案,希望它能帮助像我这样在谷歌上找到这个问题并不得不挖掘很长时间才能找到答案的人。


7
投票

在此处的文档中提到

    

从你的例子来看:


0
投票

您也可以尝试将字体写两次,这会极大地提高质量。

-4
投票

© www.soinside.com 2019 - 2024. All rights reserved.