This actually works:
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)
)
Now, this actually works. I save the outputted picture and look at it. What the produced picture is is a picture with each quadrant is moved one tile clockwise.
To make my question clearer, I’ve uploaded all the pictures here:
http://www.peterbe.com/stackoverflowquestion/index.html
But! when I stopped the debugging of each corner. Ie. I comment out all the intermediate saves so it’s not like this:
...
# debugging each tile
#lu.save('tileshifted/lu.jpg')
#ru.save('tileshifted/ru.jpg')
#ll.save('tileshifted/ll.jpg')
#rl.save('tileshifted/rl.jpg')
...
Now it stops working! And you get a composite picture where it appears that the upper left-hand corner tile has been repeated three times.
Obviously I don’t need the debugging but obviously those calls to instance.save() does something important.
UPDATE
Seems I might have found a solution. If run lu.load() right after the lu instance has been created, then it works!
Got inspiration from this one: https://stackoverflow.com/a/3838495/205832
Per the documentation for
crop: “This is a lazy operation. Changes to the source image may or may not be reflected in the cropped image. To get a separate copy, call the load method on the cropped copy.”So each of the corner crops, without the
save, is a reference to a portion of the original image, rather than a copy, so you paste LU to RU, then try to paste from RU to RL but get LU again, and so on. Thesaveapparently forces PIL to make a copy out of the crops.(Also, you didn’t actually ask a question. Your question was implicit, but if you actually go all the way to formulating a clear and concise question, then as often as not, you’ll realize the answer, or realize you need to provide more information which may lead you to the answer.)