带有 PIL 和裁剪和粘贴图片的特殊 Heisenbug

Posted

技术标签:

【中文标题】带有 PIL 和裁剪和粘贴图片的特殊 Heisenbug【英文标题】:Peculiar Heisenbug with PIL and cropping and pasting a picture 【发布时间】:2012-04-23 20:49:11 【问题描述】:

这确实有效:

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)
     )

现在,这确实有效。我保存输出的图片并查看它。生成的图片是每个象限顺时针移动一格的图片。

为了让我的问题更清楚,我在这里上传了所有图片: http://www.peterbe.com/***question/index.html

但是!当我停止每个角落的调试时。 IE。我注释掉所有中间保存,所以它不是这样的:

    ...
    # 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 实例之后立即运行lu.load(),那么它可以工作! 从中得到灵感:https://***.com/a/3838495/205832

【问题讨论】:

【参考方案1】:

根据crop 的文档:“这是一个惰性操作。对源图像的更改可能会或可能不会反映在裁剪后的图像中。要获得单独的副本,请在裁剪后的副本上调用 load 方法。”

所以每个角落裁剪,没有save,是对原始图像的一部分的引用,而不是副本,所以你将 LU 粘贴到 RU,然后尝试从 RU 粘贴到 RL,但得到 LU再次,依此类推。 save 显然迫使 PIL 从农作物中复制出来。

(另外,您实际上并没有提出问题。您的问题是含蓄的,但如果您真的一直想提出一个清晰简洁的问题,那么无论是否经常,您'会意识到答案,或者意识到你需要提供更多信息,这可能会引导你找到答案。)

【讨论】:

呵呵。这是我在发布几分钟后才发现的。

以上是关于带有 PIL 和裁剪和粘贴图片的特殊 Heisenbug的主要内容,如果未能解决你的问题,请参考以下文章

python PIL Image图片裁剪

使用Python PIL库中的Image.thumbnail函数裁剪图片

1.图像裁剪、加边框、旋转(Python PIL)

PIL库将图片转成字符

Python批量裁剪图片小脚本

如何使用 Python PIL 或 CV 裁剪图像?