Image Manipulator Script

A Python script that can take a resource image and apply a bunch of complex effects on it.

# Image Manipulator
#
# Takes a source image, applies filter images on top, then applies blur and
# opaque filters on a number of random boxes on the image before outputting.
#
# Taylan Pince (taylanpince at gmail dot com), June 22 2008
 

import os
 
from math import floor
from random import randint
from PIL import Image, ImageFilter
 

# Canvas dimensions
CANVAS_WIDTH = 1009
CANVAS_HEIGHT = 698
 
CANVAS_RATIO = float(CANVAS_WIDTH) / float(CANVAS_HEIGHT)
 
# Box dimensions
BOX_WIDTH = 201
BOX_HEIGHT = 99
 
# Number of blurred boxes
NUM_BLUR = 4
 
# Number of opaque boxes
NUM_OPAQUE = 4
 
# Grid and opaque box colours, last number controls opacity
LINE_FILL = (255, 255, 255, 90)
OPAQUE_FILL = (255, 255, 255, 60)
 

def image_manipulator(in_file, out_file):
# base_dir is the django project root, filter_dir is the imagemanip application root
base_dir = os.path.realpath(os.getcwd())
filter_dir = os.path.join(base_dir, os.path.realpath(os.path.dirname(__file__)), "filters")
# Setup source and filter images
source = Image.open(os.path.join(base_dir, in_file))
spotlight = Image.open(os.path.join(filter_dir, "spotlight.png"))
rounded_box = Image.open(os.path.join(filter_dir, "rounded-box.png"))
rounded_corners = Image.open(os.path.join(filter_dir, "rounded-corners.png"))
 
# Resize/crop source if necessary
source_ratio = float(source.size[0]) / float(source.size[1])
 
if source_ratio > CANVAS_RATIO:
source = source.resize((source.size[0] * CANVAS_HEIGHT / source.size[1], CANVAS_HEIGHT))
elif source_ratio < CANVAS_RATIO:
source = source.resize((CANVAS_WIDTH, source.size[1] * CANVAS_WIDTH / source.size[0]))
 
source = source.crop((0, 0, CANVAS_WIDTH, CANVAS_HEIGHT))
 
spotlight = spotlight.resize(source.size)
 

# Paste filters on the source
source.paste(spotlight, None, spotlight)
 

# Setup canvas and paste filters on it
canvas = Image.new("RGB", source.size)
canvas.paste(source, None)
 

# Place opaque layer on canvas
opaque = Image.new("RGBA", canvas.size, LINE_FILL)
canvas.paste(opaque, None, opaque)
 

# Place rounded corners on canvas
canvas.paste(rounded_corners, None, rounded_corners)
 

boxes = list()
 
# Populate the box list in columns and rows
for column in range(int(floor(source.size[0] / BOX_WIDTH))):
for row in range(int(floor(source.size[1] / BOX_HEIGHT))):
boxes.append((column, row))
 

# Apply the blur filter to random boxes from the list and pop them out
for i in range(NUM_BLUR):
box = boxes.pop(randint(0, (len(boxes) - 1)))
 
# We have to get a larger piece here because the blur effect causes
# smoothing on the edges
piece = source.crop((
(box[0] * BOX_WIDTH) + box[0] - 10,
(box[1] * BOX_HEIGHT) + box[1] - 10,
(box[0] * BOX_WIDTH) + box[0] + BOX_WIDTH + 10,
(box[1] * BOX_HEIGHT) + box[1] + BOX_HEIGHT + 10,
))
 
for a in range(4):
piece = piece.filter(ImageFilter.BLUR)
 
# Cut out the extra parts
piece = piece.crop((10, 10, piece.size[0] - 10, piece.size[1] - 10))
 
# Paste on the source
canvas.paste(piece, (
(box[0] * BOX_WIDTH) + box[0],
(box[1] * BOX_HEIGHT) + box[1],
(box[0] * BOX_WIDTH) + box[0] + BOX_WIDTH,
(box[1] * BOX_HEIGHT) + box[1] + BOX_HEIGHT,
), rounded_box)
 

# Apply the opaque filter to random boxes from the list
opaque_mask = Image.new("RGBA", (BOX_WIDTH, BOX_HEIGHT), OPAQUE_FILL)
 
for i in range(NUM_OPAQUE):
# Don't pop the box from the list, we want to iterate over it again
box = boxes[randint(0, (len(boxes) - 1))]
 
# Apply it to the source, not the canvas, it'll be copied later
source.paste(opaque_mask, (
(box[0] * BOX_WIDTH) + box[0],
(box[1] * BOX_HEIGHT) + box[1],
(box[0] * BOX_WIDTH) + box[0] + BOX_WIDTH,
(box[1] * BOX_HEIGHT) + box[1] + BOX_HEIGHT,
), opaque_mask)
 

# Paste all the remaining boxes applying the rounded box mask
for box in boxes:
box_coordinates = (
(box[0] * BOX_WIDTH) + box[0],
(box[1] * BOX_HEIGHT) + box[1],
(box[0] * BOX_WIDTH) + box[0] + BOX_WIDTH,
(box[1] * BOX_HEIGHT) + box[1] + BOX_HEIGHT,
)
 
piece = source.crop(box_coordinates)
 
canvas.paste(piece, box_coordinates, rounded_box)
 

# Save the final image
canvas.save(os.path.join(base_dir, out_file), quality=85)

Download this file