[Python] PIL は、最も完全なコード説明とともに画像に透かしを追加します

写真に透かしを追加する

以下はウォーターマークを追加するメソッドです。ウォーターマークを別の Python ファイルに配置して、ウォーターマークを追加する必要がある場所でこのメソッドを呼び出すことができます。

from PIL import Image, ImageDraw, ImageFont


def add_watermark(image_path, text, font_path, font_size=40, fill=(255, 255, 255, 128)):
    """
    在图片上添加水印
    :param image_path: 图片路径
    :param text: 水印文本
    :param font_path: 字体文件路径
    :param font_size: 字体大小,默认为 40
    :param fill: 水印颜色,默认为白色半透明
    :return: None
    """
    with Image.open(image_path) as image:
        draw = ImageDraw.Draw(image)
        width, height = image.size
        font = ImageFont.truetype(font_path, font_size)
        text_width, text_height = draw.textsize(text, font=font)
        x = int((width - text_width) / 2)
        y = int((height - text_height) / 2)
        draw.text((x, y), text, font=font, fill=fill)
        image.save(image_path)

このメソッドは 5 つのパラメータを受け入れます。

  • image_path: 透かしを入れる必要がある画像のパス。
  • text: 透かしテキスト;
  • font_path: フォント ファイルのパス;
  • font_size: フォント サイズ。デフォルトは 40 です。
  • fill: 透かしの色。デフォルトは白で半透明です。

必要に応じてこれらのパラメータを変更できます。

このメソッドを使用したサンプルコードは次のとおりです。

add_watermark('image.jpg', 'Hello, world!', 'simsun.ttc', font_size=50)

このコードは、テキスト、フォント、フォント サイズ 50 の透かしをimage.jpg画像。Hello, world!simsun.ttc

塗りつぶしパラメータの説明:

fillパラメータは透かしの色を指​​定します。PIL ライブラリでは色は 4 つの値で表され、4 つの値はそれぞれ赤、緑、青、透明度を表し、値の範囲は 0 ~ 255 です。たとえば、(255, 0, 0, 128)赤色の半透明を表現します。

add_watermark()メソッドでは、透かしが元の画像を完全に覆わないように、fillデフォルトのパラメーターを白と半透明に設定します。(255, 255, 255, 128)このパラメータは必要に応じて変更できます。たとえば、透かしの色を赤に変更するには、fillパラメータ(255, 0, 0, 128)

textbboxパラメータの説明

textbbox()このメソッドは、Pillow ライブラリのImageDrawモジュール、テキストの描画に必要な四角形のサイズを計算するために使用されます。メソッドの構文は次のとおりです。

ImageDraw.Draw.textbbox(xy, text, font=None, spacing=0, align='left')

このうち、各パラメータの意味は以下のとおりです。

  • xy(x, y):テキストの開始位置、つまりテキスト ボックスの左上隅の座標を示す2 つのタプル。
  • text:描画する文字の内容を示します。
  • font:ImageFont.truetype()メソッド。
  • spacing: 行間の間隔を示します。デフォルトは 0 です。
  • align: テキストの水平方向の配置を示します。'left'、 、'center'またはです'right'

textbbox()このメソッドは、テキストの内容、フォント、開始位置などの情報に基づいてテキスト ボックスのサイズを計算し、(x0, y0, x1, y1)テキスト ボックスの左上隅と右下隅の座標を示す 4 タプルを返します。このうち、(x0, y0)はテキストボックスの左上隅の座標を表し、 は(x1, y1)テキストボックスの右下隅の座標を表します。

テキストを描画するとき、最初にテキスト ボックスのサイズを計算し、次にテキスト ボックスのサイズに従ってテキストの位置を計算するtextbbox()メソッドを写真。

例外処理

警告プロンプト:

非推奨警告: textsize は非推奨であり、Pillow 10 (2023-07-01) で削除される予定です。代わりに textbbox または textlength を使用してください。text_width, text_height =draw.textsize(text, font=font)

解決:

この警告は、Pillow ライブラリの将来のバージョンではtextsize()このメソッドが非推奨となりtextbbox()textlength()代わりに または メソッドを使用することが推奨されるためです。したがって、コードを記述するときは、textsize()このメソッドの。

警告メッセージによると、コード内のtextsize()メソッドをtextbbox()またはtextlength()メソッドに置き換えることができます。たとえば、上記のコードを次のように変更します。

width, height = image.size
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(font_path, font_size)
text_width, text_height = draw.textbbox((0, 0), text, font=font)
x = int((width - text_width) / 2)
y = int((height - text_height) / 2)
draw.text((x, y), text, font=font, fill=fill)

上記のコードでは、テキストの幅と高さを計算するtextbbox()メソッド、画像のサイズとテキストのサイズに従って画像内のテキストの位置を計算し、最後にテキストを画像上に描画します。画像。これにより、textsize()メソッド。

例外draw.textbbox

text_width, text_height =draw.textbbox((10, 10), text, font=font) コードのこの部分では例外がスローされます エラー: 解凍するには値が多すぎます (2 が予想されます)

このエラーは通常、textbbox()メソッド(x0, y0, x1, y1)予期された 2 タプルの間の不一致によって発生します。(text_width, text_height)

これを修正するには、次のように、 quad の左上(x0, y0)(x1, y1)テキストの幅と高さを計算します。

# 计算文本框大小
bbox = draw.textbbox((10, 10), text, font=font)

# 计算文本宽度和高度
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]

ここでは、テキストの幅と高さを計算するbbox[2] - bbox[0]ために を使用します。bbox[3] - bbox[1]このようにして、計算された幅と高さを後で使用するためにtext_widthtext_height

textbbox()メソッドを使用する場合、返される 4 タプルの値は順序どおりである(x0, y0, x1, y1)ため、必要に応じて対応する値を抽出する必要があることに注意してください。

from PIL import Image, ImageDraw, ImageFont


def add_watermark(image_path, text, font_path, font_size=40, opacity=0.5, fill=(255, 102, 0, 128)):
    """
    在图片上添加水印
    :param image_path: 图片路径
    :param text: 水印文本
    :param font_path: 字体文件路径
    :param font_size: 字体大小,默认为 40
    :param opacity: 水印透明度,默认为 0.5
    :param fill: 水印颜色,默认为白色半透明
    :return: None
    """
    with Image.open(file_path) as image:
        draw = ImageDraw.Draw(image)
        width, height = image.size
        font = ImageFont.truetype(font_path, font_size)
        print(333)
        # text_width, text_height = draw.textbbox((10, 10), text, font=font)
        # 计算文本框大小
        bbox = draw.textbbox((10, 10), text, font=font)
        # 计算文本宽度和高度
        text_width = bbox[2] - bbox[0]
        text_height = bbox[3] - bbox[1]
        print(f"=== text_width, text_height  {
      
      text_width, text_height }")
        x = int((width - text_width) / 2)
        y = int((height - text_height) / 2)
        draw.text((x, y), text, font=font, fill=FILL)
        image.save(file_path)
中国語表示の例外

元の画像
ここに画像の説明を挿入

呼び出し方法:

if __name__ == '__main__':
    
    add_watermark('test.png', '测试!', 'simsunb.ttf', font_size=50)

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-jYNI8pkj-1684290601180) (Excel および PIL.assets/image-20230517102532955.png)]

画像の中央に test! があり、画像に透かしが表示されることを期待していますが、実際の結果を見ましたが、まだ何か問題があるようです。

中国語フォントライブラリのリファレンスを変更するだけです

if __name__ == '__main__':

    # add_watermark('test.png', '测试!', 'simsunb.ttf', font_size=50)
    add_watermark('test.png', '测试!', r'C:\Windows\Fonts\微软雅黑\msyh.ttc', font_size=50)

[外部リンク画像の転送に失敗しました。ソース サイトには盗難防止リンク メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-HzCecq1L-1684290601181) (Excel および PIL.assets/image-20230517102808833.png) 】

今、私は C:\Windows\Fonts\Microsoft Yahei\msyh.ttc このパスを使用しました。これが Windows システム フォントのデフォルトの保存場所であることをお伝えしておきます。

この時点で、画像にウォーターマークを追加する基本的な操作が実現したので、早速試してみましょう。

おすすめ

転載: blog.csdn.net/qq_41604569/article/details/130720303