web-dev-qa-db-ja.com

PythonでPILを使用して画像を別の画像に合成するにはどうすればよいですか?

ダウンロード可能なデスクトップの壁紙に変換するために、画像を取得して、新しく生成された白い背景に配置する必要があります。したがって、プロセスは次のようになります。

  1. 1440x900の寸法で新しい白い画像を生成します
  2. 既存の画像を中央に配置します
  3. 単一の画像として保存

PILでは、ImageDrawオブジェクトが表示されますが、既存の画像データを別の画像に描画できることを示すものは何もありません。誰でもお勧めできる提案やリンクはありますか?

61
Sebastian

これは、Imageインスタンスのpasteメソッドで実現できます。

from PIL import Image
img = Image.open('/path/to/file', 'r')
img_w, img_h = img.size
background = Image.new('RGBA', (1440, 900), (255, 255, 255, 255))
bg_w, bg_h = background.size
offset = ((bg_w - img_w) // 2, (bg_h - img_h) // 2)
background.paste(img, offset)
background.save('out.png')

これと他の多くのPILトリックは Nadia AlramliのPILチュートリアル でピックアップできます。

112
unutbu

Unutbus回答に基づく:

#!/usr/bin/env python

from PIL import Image
import math


def resize_canvas(old_image_path="314.jpg", new_image_path="save.jpg",
                  canvas_width=500, canvas_height=500):
    """
    Place one image on another image.

    Resize the canvas of old_image_path and store the new image in
    new_image_path. Center the image on the new canvas.
    """
    im = Image.open(old_image_path)
    old_width, old_height = im.size

    # Center the image
    x1 = int(math.floor((canvas_width - old_width) / 2))
    y1 = int(math.floor((canvas_height - old_height) / 2))

    mode = im.mode
    if len(mode) == 1:  # L, 1
        new_background = (255)
    if len(mode) == 3:  # RGB
        new_background = (255, 255, 255)
    if len(mode) == 4:  # RGBA, CMYK
        new_background = (255, 255, 255, 255)

    newImage = Image.new(mode, (canvas_width, canvas_height), new_background)
    newImage.paste(im, (x1, y1, x1 + old_width, y1 + old_height))
    newImage.save(new_image_path)

resize_canvas()

Pythonの代わりにPillow( DocumentationGitHubPyPI )を使用することを忘れないでください-PillowがPython 2.XおよびPython 3.Xで動作するようにイメージします。

7
Martin Thoma

これは似たようなことをすることです

私が始めたのは、Photoshopでその「白い背景」を生成し、PNGファイルとしてエクスポートすることでした。私はim1を取得しました(画像1)。その後、貼り付け機能を使用すると、簡単になります。

_from PIL import Image

im1 = Image.open('image/path/1.png')
im2 = Image.open('image/path/2.png')
area = (40, 1345, 551, 1625)  
im1.paste(im2, area)
                   l>(511+40) l>(280+1345)
         |    l> From 0 (move, 1345px down) 
          -> From 0 (top left, move 40 pixels right)
_

Okay so where did these #'s come from? (40, 1345, 551, 1625) im2.size (511, 280) Because I added 40 right and 1345 down (40, 1345, 511, 280) I must add them to the original image size which = (40, 1345, 551, 1625)

_im1.show() 
_

新しい画像を表示する

2
Steven Jeffers

Image.blend()? [ リンク ]

または、さらに良いことに、Image.paste()、同じリンク。

1
Felix

遅すぎるかもしれませんが、そのような画像操作では、元の画像のモデルでImageSpecField [ link ]を使用します。

0
profuel