Python Imaging Library - 文本呈现

exi*_*iva 40 python imaging python-imaging-library

我正在尝试使用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)
Run Code Online (Sandbox Code Playgroud)

exi*_*iva 62

我想出了我认为可以接受的解决方案.

我所做的是渲染文本大,比如它需要的大小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)
Run Code Online (Sandbox Code Playgroud)

你最终得到这个结果,

最后结果

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

  • 请记住,虽然字体通常为不同的尺寸提供不同的形状(不只是放大和缩小一个形状).这在较小的目标尺寸中尤其明显. (3认同)

jsb*_*eno 20

尝试使用pycairo - Cairo绘图库的python绑定 - 它可用于更精细的绘图,使用抗锯齿线等 - 并且您还可以生成基于矢量的图像

正确处理字体和布局很复杂,并且还需要使用"pango"和"pangocairo"库.虽然它们是用于严肃的字体工作(所有GTK +小部件都使用pango进行字体渲染),但是可用的docuemtnation和示例非常差.

下面的示例显示了系统中可用的打印件,并将示例文本呈现为在命令行上作为参数传递的字体系列.

# -*- 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)
Run Code Online (Sandbox Code Playgroud)

数百图像

  • 啊.对于简单的应用程序来说,这看起来像是太多的依赖项.(我试图用自制软件在10.6上设置pango和cairo)......我可能不得不重新考虑一些事情.谢谢你的帮助. (4认同)

dav*_*olm 12

我从未使用PIL,但快速浏览Draw方法的文档表明PIL提供了一种渲染简单图形的方法.Photoshop提供了一种渲染复杂图形的方法.要获得接近类似Photoshop的结果,至少需要字体提示和消除锯齿.PIL的文档甚至没有暗示拥有这样的功能.您可能希望使用可能更好地在图像上呈现文本的外部工具.例如,ImageMagick(您将需要使用8位版本,它处理标准的24位RGB).你可以在这里找到一些文字绘图样本:http://www.imagemagick.org/Usage/draw/


Bax*_*orr 6

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

draw = ImageDraw.Draw(img)
        draw.fontmode = "L"
Run Code Online (Sandbox Code Playgroud)

这里的文档中提到

  • 使用“L”仍然会产生抗锯齿文本,但“draw.fontmode =“1””有效。作为参考,这些模式记录在[此处](https://pillow.readthedocs.io/en/stable/handbook/concepts.html#concept-modes);`ImageDraw` 的 `fontmode` 成员似乎没有在任何地方记录;感谢您花时间发布此答案! (4认同)

Adi*_*kar 5

建议:使用魔杖或其他影像库

这是魔杖的例子-

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')
Run Code Online (Sandbox Code Playgroud)

出来的图像