6

私は Python の経験がありませんが、このスクリプトの所有者は応答していません。

このスクリプトに写真をドラッグしてモンタージュを作成すると、最後の写真の右端が半分切り取られてしまいます。

4 枚の写真の幅があるため、

1   2   3   4

5   6   7   8

写真4と8は通常半分になります。写真用のスペースがあります(ただし、空白です)

これは何が原因なのだろうと考えていました。

トリミングされている可能性があると思いましたが、画像の半分がインポートまたは検出されていないようです。

さて、選択した写真をスクリプトにドラッグすると、次のように出力されます http://i.imgur.com/PzNylbV.png

そのため、写真やスクリーンショットをたくさん撮って、それらを 1 つのファイルに組み合わせることができます。各写真を個別に追加する必要はありません。

各写真のサイズは最大で約 500x250 です。

ここに画像の説明を入力

編集: これはプレビューのアップロードです。画像にスロットがあることがわかりますが、それが理にかなっている場合は「消えています」。

EDIT2: このスクリプトは一度は機能しましたが、編集などはしていません。約 70 枚のスクリーンショット モンタージュに取り組んでいました。エラーも何もありません。画像のインポートを妨害するためにコンピュータが何かをしている可能性はありますか?

#!/usr/bin/env python
import os
import sys
from time import strftime
import Image
import ImageDraw
import ImageFont

# parameters
row_size = 4
margin = 3

def generate_montage(filenames):
    images = [Image.open(filename) for filename in filenames]

    width = 0
    height = 0
    i = 0
    sum_x = max_y = 0 
    width = max(image.size[1]+margin for image in images)*row_size
    height = sum(image.size[0]+margin for image in images)

    montage = Image.new(mode='RGBA', size=(width, height), color=(0,0,0,0))
    try:
        image_font = ImageFont.truetype('font/Helvetica.ttf', 18)
    except:
        try:
            image_font = ImageFont.load('font/Helvetica-18.pil')
        except:
            image_font = ImageFont.load_default()
    draw = ImageDraw.Draw(montage)
    offset_x = offset_y = 0

    i = 0
    max_y = 0
    max_x = 0
    offset_x = 0
    for image in images:
        montage.paste(image, (offset_x, offset_y))

        text_coords = offset_x + image.size[0] - 45, offset_y + 120
        draw.text(text_coords, '#{0}'.format(i+1), font=image_font)

        max_x = max(max_x, offset_x+image.size[0])
        if i % row_size == row_size-1: 
            offset_y += max_y+margin
            max_y = 0
            offset_x = 0
        else:
            offset_x += image.size[0]+margin
            max_y = max(max_y, image.size[1])

        i += 1

    if i % row_size:
        offset_y += max_y

    filename = strftime("Montage %Y-%m-%d at %H.%M.%S.png")
    montage = montage.crop((0, 0, max_x, offset_y))
    montage.save(filename)

if __name__ == '__main__':
    old_cwd = os.getcwd()

    os.chdir(os.path.dirname(sys.argv[0]))
    try:
        if len(sys.argv) > 1:
            generate_montage(sys.argv[1:])
    finally:
        os.chdir(old_cwd)
4

1 に答える 1

7

サイズ計算ではimage.size[1]、幅に使用しますが、それは高さです! 代わりにimage.size[0]、幅と高さに使用してください。image.size[1]

また、いくつかのマイナーな文体上のメモ:

  • プログラムのディレクトリから常にスクリプトを実行する必要がありますか? いずれにせよ、os.chdir(os.path.dirname(sys.argv[0]))はプログラムが として実行されることを防止する./montage.pyため、 a を使用abspathして現在のディレクトリからの呼び出しを許可することができます。
  • カウンターを更新する代わりにi、for ループを次のように変更できます。

    for i,image in enumerate(images):
    
  • 次の行は、変数が上書きされるか使用されないため、効果がありません。

    width = 0
    height = 0
    i = 0
    sum_x = max_y = 0 
    

全体として、コードは次のようになります。

#!/usr/bin/env python
import os.path
import sys
from time import strftime
import Image

row_size = 4
margin = 3

def generate_montage(filenames, output_fn):
    images = [Image.open(filename) for filename in filenames]

    width = max(image.size[0] + margin for image in images)*row_size
    height = sum(image.size[1] + margin for image in images)
    montage = Image.new(mode='RGBA', size=(width, height), color=(0,0,0,0))

    max_x = 0
    max_y = 0
    offset_x = 0
    offset_y = 0
    for i,image in enumerate(images):
        montage.paste(image, (offset_x, offset_y))

        max_x = max(max_x, offset_x + image.size[0])
        max_y = max(max_y, offset_y + image.size[1])

        if i % row_size == row_size-1:
            offset_y = max_y + margin
            offset_x = 0
        else:
            offset_x += margin + image.size[0]

    montage = montage.crop((0, 0, max_x, max_y))
    montage.save(output_fn)

if __name__ == '__main__':
    basename = strftime("Montage %Y-%m-%d at %H.%M.%S.png")
    exedir = os.path.dirname(os.path.abspath(sys.argv[0]))
    filename = os.path.join(exedir, basename)
    generate_montage(sys.argv[1:], filename)
于 2013-07-09T19:05:10.147 に答える