Modern applications, including social media filters, computer vision, and digital art, rely heavily on image processing. One common task is combining two images, seamlessly merging them for overlays, adding watermarks, or creating other artistic effects. Whether you’re blending images for artistic effects or layering graphics for branding, Python offers powerful libraries to achieve this with ease.
In this article, we’ll explore how to combine two images in Python using popular libraries like OpenCV and Pillow. We’ll walk through different methods, including alpha blending, masking, and pasting, to help you seamlessly merge images for various applications.
In this article:
- Using Pillow to Merge Images
- How to Combine Two Images in Python with OpenCV
- Automating Image Combination with Cloudinary
Using Pillow to Merge Images
When working with images in Python, Pillow is one of the most popular and flexible libraries for image processing. It provides an easy-to-use interface for performing operations such as resizing, cropping, rotating, filtering, and merging images.
Pillow simplifies image manipulation—whether you’re making collages, combining screenshots, or merging images for analysis—with only a few lines of code. Now, let’s explore how Pillow can merge two images side by side, perfectly aligned despite size differences.
To begin, make sure that Pillow is installed in your Python virtual environment. If it’s not already installed, you can add it using:
pip install pillow
Next, create a Python file in your project directory, import the module, and load the images:
from PIL import Image # Open the two images image1 = Image.open("image1.jpg") image2 = Image.open("image2.jpg")
Before merging, it’s important to check whether the images have the same dimensions. If they don’t, we should adjust their sizes to ensure they align properly. The easiest way to do this is to resize both images to match the height of the smaller one while preserving their aspect ratios:
# Get the height of the smaller image min_height = min(image1.height, image2.height) # Resize images to have the same height while maintaining the aspect ratio image1 = image1.resize((int(image1.width * min_height / image1.height), min_height)) image2 = image2.resize((int(image2.width * min_height / image2.height), min_height))
This ensures that both images have the same height, making them easier to merge seamlessly. Now, we need a blank canvas that can accommodate both images side by side:
# Create a blank image with the combined width combined_width = image1.width + image2.width combined_image = Image.new("RGB", (combined_width, min_height))
Once we have the blank canvas, we can paste both images onto it, positioning them next to each other, and finally, we can display and save the merged image. Here is what our code looks like:
from PIL import Image # Open the two images image1 = Image.open("image1.jpg") image2 = Image.open("image2.jpg") # Get the height of the smaller image min_height = min(image1.height, image2.height) # Resize images to have the same height while maintaining the aspect ratio image1 = image1.resize((int(image1.width * min_height / image1.height), min_height)) image2 = image2.resize((int(image2.width * min_height / image2.height), min_height)) # Create a blank image with combined width combined_width = image1.width + image2.width combined_image = Image.new("RGB", (combined_width, min_height)) # Paste images side by side combined_image.paste(image1, (0, 0)) combined_image.paste(image2, (image1.width, 0)) # Show and save the final merged image combined_image.show() combined_image.save("merged_image.jpg")
How to Combine Two Images in Python with OpenCV
OpenCV is another Python library that allows you to combine images easily. It is one of the most widely used libraries for computer vision, image processing, and machine learning tasks. It provides a comprehensive set of tools for manipulating images, detecting objects, applying transformations, and performing real-time processing. OpenCV is highly optimized for performance and supports various image operations, such as blending, masking, and overlays, making it an excellent choice for combining images efficiently.
To use OpenCV to merge your images, start by making sure OpenCV is installed in your Python environment. If you haven’t installed it yet, you can do so using the following pip command:
pip install opencv-python
Next, we’ll load two images and display them using OpenCV:
import cv2 # Load the two images image1 = cv2.imread("image1.jpg") image2 = cv2.imread("image2.jpg") # Display images (optional) cv2.imshow("Image 1", image1) cv2.imshow("Image 2", image2) cv2.waitKey(0) cv2.destroyAllWindows()
Here, the cv2.imread()
function loads images as NumPy arrays, which allows us to manipulate them easily. The cv2.imshow()
function is used to display the images, and cv2.waitKey(0)
ensures the windows stay open until a key is pressed.
Before we merge our images, we need to make sure both images have the same dimensions. If they have differences in dimensions, we can resize the second image to match the first one using cv2.resize()
:
# Resize second image to match the first image image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))
Now that both images are the same size, we can merge them using OpenCV’s cv2.addWeighted()
function, which allows us to control the blending ratio by adjusting alpha values:
# Blend images with alpha transparency alpha = 0.6 # Weight of the first image beta = 0.4 # Weight of the second image blended_image = cv2.addWeighted(image1, alpha, image2, beta, 0)
Here, alpha
and beta
determine how much of each image is visible in the final result. A higher alpha
value makes the first image more dominant, while a higher beta
value makes the second image more prominent. The last argument (0) is a scalar that can add brightness, but is left as zero in most cases.
Finally, we display and save the blended image. Here is what our code looks like:
import cv2 # Load the two images image1 = cv2.imread("image1.jpg") image2 = cv2.imread("image2.jpg") # Resize second image to match the first image image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0])) # Blend images with alpha transparency alpha = 0.6 # Weight of the first image beta = 0.4 # Weight of the second image blended_image = cv2.addWeighted(image1, alpha, image2, beta, 0) # Show and save the blended image cv2.imshow("Blended Image", blended_image) cv2.waitKey(0) cv2.destroyAllWindows() cv2.imwrite("blended_image.jpg", blended_image)
By adjusting the alpha
and beta
values, you can control how much each image contributes to the final result.
Automating Image Combination with Cloudinary
Installing and managing image-processing libraries like Pillow and OpenCV can be time-consuming, requiring additional dependencies, manual coding, and system compatibility checks. Handling images locally also consumes storage and processing power, making it difficult to scale for large applications.
Cloudinary eliminates these challenges by providing a cloud-based media management platform that enables dynamic image transformations without any local setup. With Cloudinary, you can overlay, merge, and manipulate images on the fly using simple URL-based transformations or an intuitive Python SDK, making it an excellent solution for scalable web applications.
Instead of writing complex image-processing code, Cloudinary allows you to merge images dynamically using transformation URLs. This makes it an essential option for e-commerce platforms, social media applications, and content delivery networks, where real-time image modifications are constantly needed.
Merging Images Using Cloudinary’s URL-Based API
With Cloudinary’s URL-based transformations, you can overlay one image onto another in a single API call. As an example, we’ll use this image from the Cloudinary demo cloud:
With Cloudinary’s dynamic URL generation, you can overlay one image onto another while setting its width and position:
https://res.cloudinary.com/demo/image/upload/l_docs:logo-semi-opaque,w_1000,x_50,y_50/cld-sample.jpg
This URL overlays docs:logo-semi-opaque
onto cld-sample.jpg
, setting its width to 1000
pixels and positioning it at (50,50). By adjusting these parameters, you can change the overlay’s size, position, opacity, and blending mode, allowing complete control over how the images are merged. Here is what our image looks like:
For more flexibility, you can integrate Cloudinary’s Python SDK to automate image combinations in your Python applications. The SDK provides an easy way to apply transformations programmatically. To use Cloudinary’s Python SDK, you will first need to install it using pip:
pip install cloudinary
Next, log in to your Cloudinary account and head over to the Programmable Media dashboard. If you don’t have a Cloudinary account, you can sign up for a free account. Now click on the Go to API Keys button to retrieve your API keys.
For this tutorial, we will upload and transform our images. Thankfully, Cloudinary provides a whole host of images that we can use. So, for now, we will be using office_desk.jpg
as well as the Cloudinary logo to overlay our images:
Now create a Python file in the project directory of your choosing and start by importing the Cloudinary Python SDK and configuring your Cloudinary credentials:
import cloudinary import cloudinary.uploader import cloudinary.api # Configure Cloudinary with your account details cloudinary.config( cloud_name="your_cloud_name", api_key="your_api_key", api_secret="your_api_secret" )
Before overlaying our images, you will first need to upload your images to the Cloudinary cloud. To do this, we will use the .upload()
method as follows:
# Upload base image base_image = cloudinary.uploader.upload('office_desk.jpg', public_id='base_image') # Upload overlay image overlay_image = cloudinary.uploader.upload('cloudinary_logo.jpg', public_id='overlay_image')
Finally, you can overlay one image onto another before printing our URL. Here is what our code looks like:
import cloudinary import cloudinary.uploader from cloudinary import CloudinaryImage # Configure Cloudinary with your account details cloudinary.config( cloud_name="your_cloud_name", api_key="your_api_key", api_secret="your_api_secret" ) # Upload base image base_image = cloudinary.uploader.upload('office_desk.jpg', public_id='base_image') # Upload overlay image overlay_image = cloudinary.uploader.upload('cloudinary_logo.jpg', public_id='overlay_image') # Generate URL with overlay and transparency url = CloudinaryImage('base_image').build_url( transformation=[ {'overlay': 'overlay_image', 'opacity': 50, 'width': 400, 'gravity': 'south_east'} ] ) print(url)
Here is what our image looks like:
Now, if you want to concatenate two images horizontally, first retrieve the width of the first image:
# Retrieve the width of the first image first_image_info = cloudinary.api.resource('first_image') first_image_width = first_image_info['width']
Then, use Cloudinary’s transformation API to position the second image to the right of the first image:
# Generate URL with the second image overlaid to the right of the first image combined_image_url = CloudinaryImage('first_image').build_url( transformation=[ {'overlay': 'second_image', 'x': first_image_width, 'gravity': 'west'} ] ) print("Combined Image URL:", combined_image_url)
Here, we use the x
parameter to position the overlay at the width of the first image, followed by using gravity: west
to align the second image to the left of the overlay.
Wrapping Up
Whether you need precise local image manipulation with Pillow and OpenCV or want the efficiency of Cloudinary’s dynamic transformation API, these tools offer flexible solutions for various applications. Experiment with these methods based on your specific needs—whether it’s watermarking, compositing, or creating engaging visuals at scale.
Try Cloudinary to simplify and automate your image processing workflows to seamlessly merge, overlay, and transform images with just a few lines of code!
Learn more:
4 Generative AI Trends in the Enterprise
You Won’t Believe Your Eyes: Combining Cloudinary’s Generative AI Transformations