New Post
Loading...

How to Chunk Images Using Python & Compress to WebP for Faster Loading

Chunk Images Using Python 

Handling large images efficiently is essential for optimizing performance in web applications, machine learning, and data processing. Chunking images—dividing them into smaller sections—can help with faster loading times, parallel processing, and improved storage management.

In this guide, we’ll explore how to use Python to split images into chunks and convert them into the WebP format for better compression and faster web performance. Whether you're a developer looking to optimize your website's images or working on an image-processing project, this Python script will streamline the process effectively.


How to Chunk Images Using Python & Compress to WebP for Faster Loading

Image Chunking & WebP Conversion

This Python script helps in two major steps:

  1. Divides an image into multiple chunks

  2. Compresses each chunk into WebP format

Python Code for Image Optimization


from PIL import Image
import cv2
import numpy as np
import os
import concurrent.futures
from tqdm import tqdm

class ImageProcessor:
    def __init__(self):
        Image.MAX_IMAGE_PIXELS = None  # Disable pixel limit for Pillow
        
    def create_chunks(self, image_path, output_dir, chunks_h=2, chunks_v=2):
        """Step 1: Divide image into chunks"""
        print("Step 1: Dividing image into chunks...")
        os.makedirs(output_dir, exist_ok=True)
        
        image = Image.open(image_path)
        chunk_width = image.width // chunks_h
        chunk_height = image.height // chunks_v
        
        chunk_number = 1
        for i in range(chunks_v):
            for j in range(chunks_h):
                left = j * chunk_width
                top = i * chunk_height
                right = left + chunk_width
                bottom = top + chunk_height
                
                chunk = image.crop((left, top, right, bottom))
                chunk.save(f'{output_dir}/{chunk_number}.png', 'PNG')
                chunk_number += 1
        
        print(f"Image divided into {chunks_h * chunks_v} chunks.")
        return chunks_h * chunks_v
    
    def convert_to_webp(self, input_path, output_path, quality=35):
        """Convert single PNG to WebP"""
        try:
            with Image.open(input_path) as img:
                if img.mode in ('RGBA', 'RGB'):
                    output_path = output_path.replace('.png', '.webp')
                    img.save(output_path, 'WEBP',
                           quality=quality,
                           lossless=False,
                           method=6,
                           exact=True)
                    
                    original_size = os.path.getsize(input_path)
                    compressed_size = os.path.getsize(output_path)
                    ratio = (1 - compressed_size/original_size) * 100
                    
                    return True, ratio, f"{original_size/1024:.1f}KB -> {compressed_size/1024:.1f}KB"
                else:
                    return False, 0, "Unsupported image mode"
        except Exception as e:
            return False, 0, str(e)
    
    def compress_images(self, input_dir, output_dir, quality=35, batch_size=4):
        """Step 2: Compress images to WebP format"""
        print("\nStep 2: Compressing images to WebP...")
        os.makedirs(output_dir, exist_ok=True)
        
        png_files = [f for f in os.listdir(input_dir) if f.endswith('.png')]
        total_files = len(png_files)
        
        if total_files == 0:
            print("No PNG files found in the input directory")
            return
        
        successful = 0
        failed = 0
        total_saved = 0
        
        with concurrent.futures.ThreadPoolExecutor(max_workers=batch_size) as executor:
            futures = []
            
            for filename in png_files:
                input_path = os.path.join(input_dir, filename)
                output_path = os.path.join(output_dir, filename)
                
                future = executor.submit(self.convert_to_webp, input_path, output_path, quality)
                futures.append((future, filename))
            
            for future, filename in tqdm(futures, desc="Converting to WebP"):
                success, ratio, result = future.result()
                
                if success:
                    successful += 1
                    total_saved += ratio
                    tqdm.write(f"\u2713 {filename}: {result} ({ratio:.1f}% smaller)")
                else:
                    failed += 1
                    tqdm.write(f"\u2717 {filename}: Failed - {result}")
        
        print(f"\nSuccessfully converted: {successful} images")
        print(f"Failed: {failed} images")
        if successful > 0:
            print(f"Average space saved: {total_saved/successful:.1f}%")

 def main():
    # Configuration
    input_image = "your_image_path.jpg"  # Replace with your image path
    chunks_dir = "image_chunks"  # Directory for image chunks
    webp_dir = "compressed_images"  # Directory for final WebP images
    
    chunks_horizontal = 2
    chunks_vertical = 2
    webp_quality = 35
    batch_size = 4
    
    # Initialize processor
    processor = ImageProcessor()
    
    # Run pipeline
    total_chunks = processor.create_chunks(input_image, chunks_dir, 
                                         chunks_horizontal, chunks_vertical)
    processor.compress_images(chunks_dir, webp_dir, webp_quality, batch_size)

 if __name__ == "__main__":
    main()

How Does This Script Enhance?

  1. Smaller image sizes improve website speed.
  2. WebP format is widely supported and provides better compression.
  3. Batch processing saves time for large image sets.
  4. Reduces hosting costs by lowering bandwidth usage.

Post a Comment

0 Comments