[英]Python Imaging Library - Text rendering
我正在嘗試使用 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)
我想出了我自己認為可以接受的解決方案。
我所做的是將文本渲染得很大,比如它需要的大小的 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)
你最終得到這個結果,
這比我之前使用相同字體獲得的要好得多。
嘗試使用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)
我從未使用過 PIL,但快速查看 Draw 方法的文檔表明 PIL 提供了一種渲染簡單圖形的方法。 Photoshop 提供了一種渲染復雜圖形的方法。 要獲得類似 Photoshop 的效果,至少需要字體提示和抗鋸齒。 PIL 的文檔甚至沒有暗示具有此類功能。 您可能需要考慮使用外部工具,該工具可以更好地在圖像上呈現文本。 例如,ImageMagick(您需要使用 8 位版本,它處理標准的 24 位 RGB)。 您可以在這里找到一些文字繪圖示例: http : //www.imagemagick.org/Usage/draw/
建議:使用 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')
在 python3 中,有一個別名字體選項。 我在任何地方都找不到這個答案,希望它可以幫助像我這樣在谷歌上發現這個問題並且不得不挖掘很長時間才能找到答案的人。
draw = ImageDraw.Draw(img)
draw.fontmode = "L"
您也可以嘗試將字體編寫兩次,這樣可以極大地提高質量。
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.