带有 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的主要内容,如果未能解决你的问题,请参考以下文章