PILを使用して画像にテキストを追加する


93

画像を読み込むアプリケーションがあり、ユーザーが画像をクリックすると、この画像のテキスト領域が表示され(を使用jquery)、ユーザーは画像にテキストを書き込むことができます。画像に追加する必要があります。

それについていくつかの調査を行った後、私はPIL(Python Imaging Library)がこれを行うのに役立つことがわかりました。そこで、いくつかの例を試してみて、その動作を確認し、画像にテキストを書き込むことに成功しました。しかし、私がそれを使っPython Shellてウェブ環境でそれを試してみると、いくつかの違いがあると思います。つまり、textareaのテキストがpxで非常に大きいということです。PILをtextareaのテキストと同じサイズにするにはどうすればよいですか?

テキストは複数行です。を使用して画像内で複数行にするにはどうすればよいPILですか?

PILを使用するよりも良い方法はありますか?これが最良の実装であるかどうか、私には完全にはわかりません。

html:

<img src="images/test.jpg"/>

編集中の画像

var count = 0;
$('textarea').autogrow();
$('img').click(function(){
    count = count + 1;
    if (count > 1){
        $(this).after('<textarea />');
        $('textarea').focus();
    }   
});

textareaを追加するjquery。また、テキスト領域は、position:absoluteおよびfixedサイズです。

画像上のテキストエリアの座標を取得できるように、フォーム内に配置する必要がありますか?ユーザーがクリックしたときに画像にテキストを書き込んで画像に保存したい。


PILを使用して画像にテキストを書き込む理由(そして、PILがそれで役立つかどうかはわかりません)。スライダーで最も一般的に使用されるオーバーレイでテキストを表示するのに十分ではありませんか。
2013年

1
画像を保存するプロジェクトで必要です。PilはImageDrawを使用して画像にテキストを描画できますが、別の方法があるかどうかはわかりません。
Apostolos 2013年

それは役に立ちます、あなたが使っているPythonコードを提供できるなら?
2013年

djangoにはまだ実装されていません。インタラクティブなPythonコンソールでPILがどのように機能するかを確認しようとしました。最初に動作するかどうかを確認してから、Djangoに転送します。
Apostolos 2013年

コードの$記号は何ですか?
ムゲン、

回答:


171

で利用可能なImageFontモジュールPILは、テキストのフォントサイズの問題の解決に役立つはずです。適切なフォントの種類とサイズを確認し、次の関数を使用してフォントの値を変更します。

# font = ImageFont.truetype(<font-file>, <font-size>)
# font-file should be present in provided path.
font = ImageFont.truetype("sans-serif.ttf", 16)

したがって、コードは次のようになります。

from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw 

img = Image.open("sample_in.jpg")
draw = ImageDraw.Draw(img)
# font = ImageFont.truetype(<font-file>, <font-size>)
font = ImageFont.truetype("sans-serif.ttf", 16)
# draw.text((x, y),"Sample Text",(r,g,b))
draw.text((0, 0),"Sample Text",(255,255,255),font=font)
img.save('sample-out.jpg')

フォントサイズを計算するために、追加の作業が必要になる場合があります。ユーザーがで提供したテキストの量に基づいて変更する場合TextArea

テキストの折り返し(複数行のもの)を追加するには、1行にいくつの文字が入るかを大まかに把握します。次に、基本的に各行の最後の文字を見つけて、テキストの前処理関数を記述できます。この文字の前の空白を改行に変換します。


1
それが私の最初の考えです。それで、フォントを機能させるために、Webサーバーの特定のフォルダーにフォントを置く必要がありますか?テキストの折り返し?標準的な方法はありますか、それとも実装する必要がありますか?
Apostolos

フォントファイルは、Webサーバーのどこにでも保存できます。指定したパスが正しいことを確認してください。
ラリット

7
@lalit Windowsマシンでコードを試したところ、フォントのエラーが発生しましたself.font = core.getfont(file, size, index, encoding) IOError: cannot open resource。フォントファイルへのパスを指定するにはどうすればよいですか?
LWZ 2013

3
@LWZ、上記のコードを実行するには、フォントファイルが上記のコードを実行している現在のディレクトリにあることを確認してください。プログラムで使用する場合は、ファイルのフルパスを指定するだけです(例: 'C:\ Windows \ Fonts \ sans-serif.ttf')。ここで確認する必要があるその他のことは、ファイルに適切な読み取り権限を与えることです。
2013

3
font = ImageFont.truetype( "./ arial.ttf"、30); draw.textsize(msg、font = font);
WeizhongTu

16

プロジェクトのルートにディレクトリ「フォント」を作成し、そこにフォント(sans_serif.ttf)ファイルを置くことができます。次に、このようなものを作ることができます:

fonts_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fonts')
font = ImageFont.truetype(os.path.join(fonts_path, 'sans_serif.ttf'), 24)

15

さらに最小限の例(「Hello world!」を黒で描画し、デフォルトのフォントを画像の左上に表示します):

...
from PIL import ImageDraw
...
ImageDraw.Draw(
    image  # Image
).text(
    (0, 0),  # Coordinates
    'Hello world!',  # Text
    (0, 0, 0)  # Color
)

6

まず、フォントタイプをダウンロードする必要があります...例:https : //www.wfonts.com/font/microsoft-sans-serif

その後、次のコードを使用してテキストを描画します。

from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw 
img = Image.open("filename.jpg")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(r'filepath\..\sans-serif.ttf', 16)
draw.text((0, 0),"Draw This Text",(0,0,0),font=font) # this will draw text with Blackcolor and 16 size

img.save('sample-out.jpg')

4

Pillowでは、ImageDrawモジュールを使用して画像に描画することもできます。線、点、楕円、長方形、円弧、ビットマップ、コード、ピーススライス、ポリゴン、形状、テキストを描画できます。

from PIL import Image, ImageDraw
blank_image = Image.new('RGBA', (400, 300), 'white')
img_draw = ImageDraw.Draw(blank_image)
img_draw.rectangle((70, 50, 270, 200), outline='red', fill='blue')
img_draw.text((70, 250), 'Hello World', fill='green')
blank_image.save('drawn_image.jpg')

new()メソッドでImageオブジェクトを作成します。これは、読み込まれた画像のないImageオブジェクトを返します。次に、画像を保存する前に、長方形とテキストを画像に追加します。


3

他の回答で言及されていないことの1つは、テキストサイズの確認です。多くの場合、テキストが画像に収まるようにする(サイズが大きすぎる場合はテキストを短くする)か、テキストを描画する場所を決定する(例:テキストを上中央に揃える)必要があります。Pillow / PILは、テキストサイズをチェックする2つの方法を提供します。1つはImageFont経由、もう1つはImageDraw経由です。以下に示すように、フォントは複数の線を処理しませんが、ImageDrawは処理します。

In [28]: im = Image.new(mode='RGB',size=(240,240))                                                            
In [29]: font = ImageFont.truetype('arial')
In [30]: draw = ImageDraw.Draw(im)
In [31]: t1 = 'hello world!'
In [32]: t2 = 'hello \nworld!'
In [33]: font.getsize(t1), font.getsize(t2) # the height is the same
Out[33]: ((52, 10), (60, 10)) 
In [35]: draw.textsize(t1, font), draw.textsize(t2, font)  # handles multi-lined text
Out[35]: ((52, 10), (27, 24)) 

-7

画像ファイルにテキストを追加するには、以下のコードをコピーして貼り付けます

<?php
$source = "images/cer.jpg";
$image = imagecreatefromjpeg($source);
$output = "images/certificate".rand(1,200).".jpg";
$white = imagecolorallocate($image,255,255,255);
$black = imagecolorallocate($image,7,94,94);
$font_size = 30;
$rotation = 0;
$origin_x = 250;
$origin_y = 450;
$font = __DIR__ ."/font/Roboto-Italic.ttf";
$text = "Dummy";
$text1 = imagettftext($image,$font_size,$rotation,$origin_x,$origin_y,$black,$font,$text);
     imagejpeg($image,$output,99);
?> <img src="<?php echo $output; ?>"> <a href="<?php echo $output;    ?>" download="<?php echo $output; ?>">Download Certificate</a>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.