I am learning OpenCV and tried to paste a small image over a large image. But, it showed an error as both the images should have an equal size. I have also tried to follow the suggestion provided (How to paste an image onto a larger image using Pillow?) and (How do you composite an image onto another image with PIL in Python?)
import cv2 as cv
from scipy import ndimage
img1 = cv.imread('Please put your file name')
top_left_x = min([x1,x2,x3,x4])
top_left_y = min([y1,y2,y3,y4])
bot_right_x = max([x1,x2,x3,x4])
bot_right_y = max([y1,y2,y3,y4])
y_right =bot_right_y + 1
x_right =bot_right_x + 1
cropped = img[top_left_y: y_right, top_left_x: x_right]
rotate = ndimage.rotate(cropped, ang)
The final output image should be at centre.
This is a Pure PIL solution:-
from PIL import Image
img1 = Image.open(r"Source_Image_path")
# The values used to crop the original image (will form a bbox)
x1, y1, x2, y2 = 10, 10, 400, 400
# The angle at which the cropped Image must be rotated
angle = 50
# cropping the original image
img = img1.crop((x1, y1, x2, y2))
# Firstly converting the Image mode to RGBA, and then rotating it
img = img.convert("RGBA").rotate(angle, resample=Image.BICUBIC)
# calibrating the bbox for the beginning and end position of the cropped image in the original image
# i.e the cropped image should lie in the center of the original image
x1 = int(.5 * img1.size[0]) - int(.5 * img.size[0])
y1 = int(.5 * img1.size[1]) - int(.5 * img.size[1])
x2 = int(.5 * img1.size[0]) + int(.5 * img.size[0])
y2 = int(.5 * img1.size[1]) + int(.5 * img.size[1])
# pasting the cropped image over the original image, guided by the transparency mask of cropped image
img1.paste(img, box=(x1, y1, x2, y2), mask=img)
# converting the final image into its original color mode, and then saving it
img1.convert(img1.mode).save("Destination_path")
INPUT IMAGE:-

OUTPUT IMAGE:-

The code itself is self explanatory, but you might be wondering why are we converting the cropped image back and forth to RGBA. The reason for that is, because if we rotate a non alpha image in PIL, we end up with black bars/edges on the image where the pixel values no longer exists (read this question for more). But if we do the same for an alpha image, i.e passing an alpha image via rotate() then the empty pixel values end up being fully transparent (or alpha = 0).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With