web-dev-qa-db-ja.com

Python Imaging Library-テキストレンダリング

PILを使用してテキストをレンダリングしようとしていますが、結果は、率直に言って、がらくたです。

たとえば、Photoshopで書いたテキストを次に示します。

PhotoShop

そして、PILから出てくるもの:

PIL

ご覧のとおり、PILの結果は満足のいくものではありません。たぶん私はうるさいだけなのかもしれませんが、PILを使用してテキストを描画して、参照画像により近い結果を得る方法はありますか?

Python 2.7 with 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)
39
exiva

受け入れられると思う独自のソリューションを思いつきました。

私がやったのは、必要なサイズの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

これは、同じフォントで以前に得ていたものよりもはるかに優れています。

61
exiva

pycairo を使用してみてください-python Cairo描画ライブラリのバインディング-アンチエイリアス処理された線など、より洗練された描画に役立ちます-そして、ベクトルを生成できますベースの画像も

フォントとレイアウトの適切な処理は複雑であり、「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

20
jsbueno

PILを使用したことはありませんが、Drawメソッドのドキュメントを簡単に確認すると、PILがsimpleグラフィックスをレンダリングする方法を提供していることがわかります。 Photoshopは、グラフィックスをレンダリングする方法を提供します複雑なグラフィックス。 Photoshopに近い結果を得るには、少なくとも、フォントのヒントとアンチエイリアスが必要です。 PILのドキュメンテーションは、そのような機能を持つことをほのめかしません。画像上にテキストをレンダリングするより良い仕事をするかもしれない外部ツールを使用して見てみたいと思うかもしれません。たとえば、ImageMagick(標準の24ビットRGBを処理する8ビットバージョンを使用します)。いくつかのテキスト描画サンプルはこちらにあります: http://www.imagemagick.org/Usage/draw/

12
dave-holm

提案:ワンドまたは別のイメージングライブラリを使用する

ワンドの例を次に示します-

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-

4
Aditya Shankar

また、フォントを2回作成して、品質を大幅に向上させることもできます。

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)
0
sharpshadow