0

これは実際に機能します:

def tileshift(original, size, iterations):
    im = Image.open(original)
    format = im.format

    x, y = [float(v) for v in im.size]
    xr, yr = [float(v) for v in size]
    r = max(xr / x, yr / y)
    im = im.resize((int(round(x * r)), int(round(y * r))),
               resample=Image.ANTIALIAS)

    corners = _corners(im.size)
    lu = im.crop(corners[0])
    ru = im.crop(corners[1])
    ll = im.crop(corners[2])
    rl = im.crop(corners[3])

    # debugging each tile
    lu.save('tileshifted/lu.jpg')
    ru.save('tileshifted/ru.jpg')
    ll.save('tileshifted/ll.jpg')
    rl.save('tileshifted/rl.jpg')

    im.paste(lu, corners[1])
    im.paste(ru, corners[3])
    im.paste(ll, corners[0])
    im.paste(rl, corners[2])
    return (im, format)

def _corners(size):
    w, h = size
    return (
      (0, 0, w / 2, h / 2),
      (w / 2, 0, w, h / 2),
      (0, h / 2, w / 2, h),
      (w / 2, h / 2, w, h)
     )

さて、これは実際に機能します。出力した絵を保存して眺めています。生成される画像は、各象限が時計回りに 1 タイル移動された画像です。

私の質問をより明確にするために、ここにすべての写真をアップロードしました: http://www.peterbe.com/stackoverflowquestion/index.html

しかし!各コーナーのデバッグを停止したとき。すなわち。すべての中間保存をコメントアウトするので、次のようにはなりません:

    ...
    # debugging each tile
    #lu.save('tileshifted/lu.jpg')
    #ru.save('tileshifted/ru.jpg')
    #ll.save('tileshifted/ll.jpg')
    #rl.save('tileshifted/rl.jpg')
    ...

今、それは機能しなくなりました!そして、左上隅のタイルが 3 回繰り返されたように見える合成画像が得られます。

明らかにデバッグは必要ありませんが、明らかにこれらの呼び出しinstance.save()は重要なことを行います。

アップデート

私は解決策を見つけたかもしれないようです。インスタンスが作成されlu.load()た直後に実行すると、機能します。luこれからインスピレーションを得ました: https://stackoverflow.com/a/3838495/205832

4

1 に答える 1

3

のドキュメントによると、crop「これは怠惰な操作です。ソース画像への変更は、トリミングされた画像に反映される場合と反映されない場合があります。別のコピーを取得するには、トリミングされたコピーで load メソッドを呼び出します。」

したがって、 のない各コーナー トリミングはsave、コピーではなく、元のイメージの一部への参照であるため、LU を RU に貼り付けてから、RU から RL に貼り付けようとしますが、再び LU を取得します。これsaveにより、PIL は作物からコピーを作成するように強制されるようです。

(また、実際に質問をしたわけではありません。あなたの質問は暗示的なものでしたが、実際に明確で簡潔な質問を定式化するまで行った場合、多くの場合、答えに気付くか、必要性に気付くでしょう。答えにつながる可能性のある詳細情報を提供します。)

于 2012-04-23T20:54:15.627 に答える