Pillow
Pillow copied to clipboard
`image.paste(image, box=(x, y))` is unexpected if both images are identical and `y` is positive
I searched for a solution to get a high performance shift operation with Pillow (in-place, SIMD, executed on C-level) but have not found one. It seems they all require one/multiple memory allocations or manual python loops.
I then realized image.paste(image, box) should do it. But the resulting image shifts the y-amount again and again (if y is positive).
My first guess was that I used the box parameter wrongly, but image.paste(image.copy(), box) works as expected.
I conclude that a check is missing if the image pasted in is the same like self or that it should get mentioned in the docs that in this case the function has a different semantic.
Maybe, if copying started from below would fix the given example.
When box=(0, -10), it works as expected.
Repeatedly shifted, working unexpected:
img = Image.open("some_random_image.jpg")
img.paste(img, box=(0, 10))
img.save("img_pasted.jpg")
Working as expected:
img = Image.open("some_random_image.jpg")
img.paste(img.copy(), box=(0, 10))
img.save("img_pasted.jpg")
img = Image.open("some_random_image.jpg")
img.paste(img, box=(0, -10))
img.save("img_pasted.jpg")
img = Image.open("some_random_image.jpg")
img.paste(img, box=(-10, -10))
img.save("img_pasted.jpg")
img = Image.open("some_random_image.jpg")
img.paste(img, box=(10, -10))
img.save("img_pasted.jpg")
img = Image.open("some_random_image.jpg")
img.paste(img, box=(0, 0))
img.save("img_pasted.jpg")
img = Image.open("some_random_image.jpg")
img.paste(img, box=(-10, 0))
img.save("img_pasted.jpg")
img = Image.open("some_random_image.jpg")
img.paste(img, box=(10, 0))
img.save("img_pasted.jpg")
To sum up: if other_img is self, and box parameter is given and is box=(x, y) with y > 0 it works unexpected. All other combinations work as expected. When a deep-copy of the image is given, all combinations of x and y work already as expected.
img.paste(img, box=(x, y))should always give the same result likeimg.paste(img.copy(), box=(x, y))for all possible combinations ofxandy.
Unfortunately, the single case that does not work is exactly my use-case for fast frame manipulation.
I've created #8882. That should fix the resulting image.
Perfect, thank you very much!