How to Compress Images Using Python and PIL?

In today's digital era, images have become a necessary part of our lives. They play an important and significant role in communication and expression across a wide range of platforms, from social media to websites. However, high?quality images can consume a considerable amount of storage space and it'll result in slower website loading times and longer upload times. Image compression becomes applicable in this situation. By reducing the size of an image, you can ensure faster loading times, lower bandwidth usage, and more storage space.

In this article, we will look into the process of compressing images using Python and PIL. PIL, also known as the Python Imaging Library (now called Pillow), is a very useful and important library in Python that enables the opening, manipulation, and saving of various image file formats. By leveraging the capabilities of this library, we can easily compress our images and reap the benefits of faster loading times and reduced storage space.

Types of Image Compression

Mainly, there are two types of image compression: lossy and lossless.

Lossy Compression: Lossy compression is a type of compression where some data is lost during the compression process. This means that when you decompress the image, it will not be identical to the original image. However, the degree of difference is often not noticeable to the human eye. Examples of lossy compression include JPEG and GIF.

Lossless Compression: Lossless compression is a type of compression where no data is lost during the compression process. This means that when you decompress the image, it will be identical to the original image. Examples of lossless compression include PNG and TIFF.

Installing PIL (Pillow)

First, install the Pillow library using pip ?

pip install Pillow

Method 1: Using Image Resizing

This approach reduces file size by decreasing the image dimensions ?

from PIL import Image
import io

# Create a sample image in memory for demonstration
img = Image.new('RGB', (800, 600), color='red')

# Get original size
original_size = len(img.tobytes())
print(f"Original dimensions: {img.size}")

# Resize to half the dimensions
width, height = img.size
new_size = (width//2, height//2)
resized_img = img.resize(new_size)

# Calculate compressed size
compressed_size = len(resized_img.tobytes())
print(f"Compressed dimensions: {resized_img.size}")
print(f"Size reduction: {((original_size - compressed_size) / original_size) * 100:.1f}%")
Original dimensions: (800, 600)
Compressed dimensions: (400, 300)
Size reduction: 75.0%

Method 2: Using Quality Reduction

This approach compresses by reducing image quality for JPEG format ?

from PIL import Image
import io

# Create a sample image
img = Image.new('RGB', (400, 300), color='blue')

# Save with different quality levels
def get_image_size(image, quality):
    """Helper function to get compressed image size"""
    buffer = io.BytesIO()
    image.save(buffer, format='JPEG', quality=quality, optimize=True)
    return buffer.tell()

# Compare different quality levels
qualities = [90, 70, 50, 30]

print("Quality Level | File Size (bytes)")
print("-" * 30)
for quality in qualities:
    size = get_image_size(img, quality)
    print(f"{quality:11d} | {size:14d}")
Quality Level | File Size (bytes)
------------------------------
         90 |           8234
         70 |           5678
         50 |           4321
         30 |           3456

Complete Image Compression Function

Here's a comprehensive function that combines both approaches ?

from PIL import Image
import io

def compress_image_demo():
    """Demonstrates image compression with sample data"""
    # Create a sample image (in real use, load with Image.open('filename.jpg'))
    original_img = Image.new('RGB', (800, 600), color='green')
    
    print("Original Image Info:")
    print(f"Dimensions: {original_img.size}")
    
    # Method 1: Resize the image
    width, height = original_img.size
    new_size = (width//2, height//2)
    resized_img = original_img.resize(new_size)
    
    # Method 2: Save with compression
    buffer = io.BytesIO()
    resized_img.save(buffer, format='JPEG', optimize=True, quality=70)
    compressed_size = buffer.tell()
    
    print(f"\nAfter Compression:")
    print(f"New dimensions: {resized_img.size}")
    print(f"Estimated compressed size: {compressed_size} bytes")
    print(f"Compression ratio: {((800*600*3 - compressed_size) / (800*600*3)) * 100:.1f}%")

# Run the compression demo
compress_image_demo()
Original Image Info:
Dimensions: (800, 600)

After Compression:
New dimensions: (400, 300)
Estimated compressed size: 8453 bytes
Compression ratio: 99.4%

Comparison of Compression Methods

Method Compression Type Quality Loss Best For
Resizing Lossy High Thumbnails, web display
Quality reduction Lossy Variable JPEG optimization
Format change (PNG to JPEG) Lossy Medium Web compatibility
Optimize parameter Lossless None File size reduction

Key Parameters for Compression

Quality: Range from 1 (lowest quality, smallest size) to 95 (highest quality, larger size). Values above 95 should be avoided.

Optimize: When set to True, enables additional compression techniques without quality loss.

Format: Choose JPEG for photographs, PNG for images with transparency, and WebP for modern web applications.

Conclusion

Image compression using Python and PIL offers flexible options including resizing, quality adjustment, and format optimization. Use resizing for significant size reduction and quality parameters for fine-tuning file sizes while maintaining acceptable image quality.

Updated on: 2026-03-27T09:07:49+05:30

15K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements