PythonのPILを使用して斜めにテキストを描画するにはどうすればよいですか?
-
05-07-2019 - |
質問
Pythonを使用して、PILを使用してさまざまな角度でテキストを描画できるようにします。
たとえば、時計の文字盤の周りに数字を描いているとします。数字 3 は期待どおりに表示されますが、 12 は反時計回りに90度回転して描画されます。
したがって、さまざまな角度でさまざまな文字列を描画できる必要があります。
解決
テキストを一時的な空白の画像に描画し、回転させてから、元の画像に貼り付けます。関数のステップをまとめることができます。使用する正確な座標を見つけ出すのに幸運です-私の冷たく曇った脳は今のところそれまでではありません。
このデモでは、画像の上の斜めに黄色のテキストを書き込みます:
# Demo to add rotated text to an image using PIL
import Image
import ImageFont, ImageDraw, ImageOps
im=Image.open("stormy100.jpg")
f = ImageFont.load_default()
txt=Image.new('L', (500,50))
d = ImageDraw.Draw(txt)
d.text( (0, 0), "Someplace Near Boulder", font=f, fill=255)
w=txt.rotate(17.5, expand=1)
im.paste( ImageOps.colorize(w, (0,0,0), (255,255,84)), (242,60), w)
他のヒント
Imageオブジェクトを作成する前に、ピクセル単位でテキストのサイズを知ることも役立ちます。グラフを描くときにこのようなコードを使用しました。その後、私は問題がなかった、例えばデータラベルの配置(画像はテキストとまったく同じ大きさです)。
(...)
img_main = Image.new("RGB", (200, 200))
font = ImageFont.load_default()
# Text to be rotated...
rotate_text = u'This text should be rotated.'
# Image for text to be rotated
img_txt = Image.new('L', font.getsize(rotate_text))
draw_txt = ImageDraw.Draw(img_txt)
draw_txt.text((0,0), rotate_text, font=font, fill=255)
t = img_value_axis.rotate(90, expand=1)
2つの画像を結合する残りの部分については、このページで既に説明しています。 「不規則」に回転した場合角度、このコードを少し改善する必要があります。実際には90、180、270で機能します...
これが簡単になるとか、このソリューションが必ずしもあなたにとって完璧になるとは言いませんが、こちらのドキュメントをご覧ください:
http://effbot.org/imagingbook/pil-index.htm
特にImage、ImageDraw、およびImageFontモジュールに注意を払ってください。
次の例が役立ちます。
import Image
im = Image.new("RGB", (100, 100))
import ImageDraw
draw = ImageDraw.Draw(im)
draw.text((50, 50), "hey")
im.rotate(45).show()
本当にしたいことをするためには、正しく回転したテキスト画像の束を作り、それらをすべてより洗練された操作で一緒に組み立てる必要があるかもしれません。そして、結局のところ、まだ見栄えがよくないかもしれません。たとえば、アンチエイリアスなどがどのように処理されるかはわかりませんが、うまくいかないかもしれません。幸運を祈ります。簡単な方法があれば、私も知りたいと思います。
これは答えに触発された作業バージョンですが、画像を開いたり保存したりしなくても機能します。
2つの画像には、何が起こっているのかを示すために、0以外の色付きの背景とアルファチャネルがあります。 2つのアルファチャネルを92から0に変更すると、完全に透明になります。
from PIL import Image, ImageFont, ImageDraw
text = 'TEST'
font = ImageFont.truetype(r'C:\Windows\Fonts\Arial.ttf', 50)
width, height = font.getsize(text)
image1 = Image.new('RGBA', (200, 150), (0, 128, 0, 92))
draw1 = ImageDraw.Draw(image1)
draw1.text((0, 0), text=text, font=font, fill=(255, 128, 0))
image2 = Image.new('RGBA', (width, height), (0, 0, 128, 92))
draw2 = ImageDraw.Draw(image2)
draw2.text((0, 0), text=text, font=font, fill=(0, 255, 128))
image2 = image2.rotate(30, expand=1)
px, py = 10, 10
sx, sy = image2.size
image1.paste(image2, (px, py, px + sx, py + sy), image2)
image1.show()