我正在尝试使用PIL渲染一些文本,但坦白说,结果是废话。
例如,这是我在Photoshop中写的一些文字:
以及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)
答案 0 :(得分:59)
我想出了我认为可以接受的解决方案。
我所做的是渲染文字大,就像它需要的大小的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)
你最终得到了这个结果,
比使用相同字体的情况要好得多。
答案 1 :(得分: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)
答案 2 :(得分:12)
我从未使用PIL,但快速查看Draw方法的文档表明PIL提供了一种渲染简单图形的方法。 Photoshop提供了一种渲染复杂图形的方法。要获得接近类似Photoshop的结果,至少需要字体提示和抗锯齿。 PIL的文档甚至没有暗示拥有这样的功能。您可能希望使用可能更好地在图像上呈现文本的外部工具。例如,ImageMagick(您将需要使用8位版本,它处理标准的24位RGB)。您可以在此处找到一些文字绘图示例:http://www.imagemagick.org/Usage/draw/
答案 3 :(得分:3)
建议:使用Wand或其他成像库
这是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')
答案 4 :(得分:2)
在python3中,有一个别名字体选项。我在任何地方都找不到这个答案,希望它可以帮助像我这样的人在Google上找到这个问题,并且不得不花很长时间才能找到答案。
draw = ImageDraw.Draw(img)
draw.fontmode = "L"
答案 5 :(得分:-1)
您还可以尝试将字体写入两次,以提高质量。
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)