New Post
Loading...

How to Merge Images in Python: A Complete Guide for Beginners

How to Merge Images in Python

Merging images is a crucial technique in image processing. It is often used to create collages, blend graphics, and enhance visuals. With its robust libraries like Pillow and OpenCV, Python provides seamless solutions for effortlessly merging images. In this comprehensive guide, we will explore different ways to merge images in Python with easy-to-follow code examples.

How to Merge Images in Python


Why Merge Images in Python?

Merging images is widely used in:

  1. Creating collages for social media posts and advertisements.
  2. Stitching images for panoramic photography
  3. Enhancing visual effects in graphic design
  4. Combining datasets for machine learning models

With Python’s image processing libraries, you can merge images with precision, customize their alignment, and even blend them smoothly for professional results.


Method 1: Merging Images Using Pillow (PIL)

Pillow, an advanced version of the Python Imaging Library (PIL), is a simple yet powerful library for handling images.

Step 1: Install Pillow

Before getting started, install Pillow using pip:

pip install pillow


Step 2: Merge Images Horizontally or Vertically

Here’s how you can merge two images side by side or on top of each other:

from PIL import Image, ImageFile
 import numpy as np
 import os

 # Disable the decompression bomb check
 Image.MAX_IMAGE_PIXELS = None
 # Allow loading of truncated images
 ImageFile.LOAD_TRUNCATED_IMAGES = True

 def merge_images_seamless(image_paths, output_path, grid_size=(2, 2), scale_factor=None):

    if len(image_paths) != grid_size[0] * grid_size[1]:
        raise ValueError(f"Expected {grid_size[0] * grid_size[1]} images for a {grid_size[0]}x{grid_size[1]} grid, but got {len(image_paths)}")
    
    # Open all images
    print("Opening images...")
    images = []
    for img_path in image_paths:
        try:
            img = Image.open(img_path)
            # Convert to RGB to ensure consistent format
            if img.mode != 'RGB':
                img = img.convert('RGB')
            
            # Resize if scale factor is provided
            if scale_factor and scale_factor != 1.0:
                new_width = int(img.width * scale_factor)
                new_height = int(img.height * scale_factor)
                img = img.resize((new_width, new_height), Image.LANCZOS)
                print(f"Resized {img_path} to {new_width}x{new_height}")
            
            images.append(img)
            print(f"Successfully loaded {img_path} with size {img.width}x{img.height}")
        except Exception as e:
            print(f"Error opening {img_path}: {e}")
            # Create a placeholder
            placeholder = Image.new('RGB', (1000, 1000), color='gray')
            images.append(placeholder)
    
    # Find the dimensions for each row and column
    print("Stitching images...")
    rows = []
    for r in range(grid_size[0]):
        row_images = [images[r * grid_size[1] + c] for c in range(grid_size[1])]
        rows.append(row_images)
    
    # Memory-efficient approach: stitch one row at a time
    final_height = sum(max(img.height for img in row) for row in rows)
    final_width = max(sum(img.width for img in row) for row in rows)
    
    print(f"Creating final image with dimensions {final_width}x{final_height}")
    result = Image.new('RGB', (final_width, final_height))
    
    y_offset = 0
    for row in rows:
        row_height = max(img.height for img in row)
        x_offset = 0
        
        for img in row:
            result.paste(img, (x_offset, y_offset))
            x_offset += img.width
        
        y_offset += row_height
    
    print(f"Saving final image to {output_path}")
    result.save(output_path)
    print(f"Seamlessly merged image saved to {output_path}")

 # Example usage
 if __name__ == "__main__":
    # Replace these with your actual image paths
    images = [
        "/Users/apple/Documents/Flutter/high/1.png",
        "/Users/apple/Documents/Flutter/high/2.png",
        "/Users/apple/Documents/Flutter/high/3.png",
        "/Users/apple/Documents/Flutter/high/4.png"
    ]
    
    # Replace with your desired output path
    output_file = "flutterMarge.jpg"
    
    # Run the merge function with a scale factor to reduce memory usage
    # Use 0.5 for half size, 0.25 for quarter size, etc.
    merge_images_seamless(images, output_file, scale_factor=0.25)

Post a Comment

0 Comments