Skip to content

image.paste(image, box=(x, y)) is unexpected if both images are identical and y is positive #8881

@ghost

Description

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 like img.paste(img.copy(), box=(x, y)) for all possible combinations of x and y.

Unfortunately, the single case that does not work is exactly my use-case for fast frame manipulation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions