Skip to content

Conversation

@radarhere
Copy link
Member

Resolves #8881

When pasting an image,

for (y = 0; y < ysize; y++) {
memcpy(imOut->image[y + dy] + dx, imIn->image[y + sy] + sx, xsize);
}

will copy the rows of the image from top to bottom.

However, if the image is pasting onto itself, but say, 10 pixels lower,
after those 10 rows, it will start reading from a part of the image that has already been written to. This results in a repeating effect.

from PIL import Image
im = Image.open("Tests/images/hopper.png")
im.paste(im, (0, 10))

repeat

A solution for that situation is to instead copy the rows of the image from bottom to top.

copy

@ghost
Copy link

ghost commented Apr 11, 2025

It seems there is a different C-code that is called if a mask is available.
Maybe your fix works here, too. Have you tested it with a mask?

mask = Image.new("1", img.size, 1) # mask without an effect just to make sure that also the mask is tested

img.paste(
    img,
    box=(0, 10),
    mask=mask,
)
img.save("img_pasted.png")

@radarhere
Copy link
Member Author

Ok, I've pushed a commit to cover masks as well.


#include "Imaging.h"

#define PREPARE_PASTE_LOOP() \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be a function instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

radarhere@be8209e is what would be required. I don't think it's as neat, but let me know if you disagree.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, let's go with this PR version.

@hugovk hugovk merged commit 9042234 into python-pillow:main Oct 15, 2025
56 checks passed
@radarhere radarhere deleted the paste branch October 15, 2025 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants