Skip to content

Instantly share code, notes, and snippets.

@alex-spataru
Created October 17, 2023 18:22
Show Gist options
  • Save alex-spataru/6070b1fa52ccfc3dcdfa32381bfc6545 to your computer and use it in GitHub Desktop.
Save alex-spataru/6070b1fa52ccfc3dcdfa32381bfc6545 to your computer and use it in GitHub Desktop.
Python script to add drop shadows to *.png files in a directory
#
# Copyright (c) 2023 Alex Spataru <https://github.com/alex-spataru>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
import os
import re
import argparse
from PIL import Image, ImageFilter, ImageChops
def add_drop_shadow(image_path, output_path, multiplier=1):
"""Add a drop shadow to an image.
Args:
image_path (str): Path to the source image.
output_path (str): Path to save the image with shadow.
multiplier (int): Image resolution multiplier (1 for standard, >1 for HiDPI).
"""
# Load the image
img = Image.open(image_path).convert("RGBA")
# Blur radius calculation based on multiplier
blur_radius = 7.5 * multiplier
# Generate shadow
shadow = img.filter(ImageFilter.GaussianBlur(blur_radius))
shadow = ImageChops.multiply(shadow, Image.new("RGBA", img.size, (0, 0, 0, 150)))
# Crop the shadow so it fits within the image boundaries
x0 = (shadow.width - img.width) // 2
y0 = (shadow.height - img.height) // 2
shadow = shadow.crop((x0, y0, x0 + img.width, y0 + img.height))
# Combine original image and shadow
result = Image.alpha_composite(shadow, img)
# Save result
result.save(output_path)
if __name__ == '__main__':
# CLI Argument Parsing
parser = argparse.ArgumentParser(description='Add drop shadow to all PNG images in a directory.')
parser.add_argument('dir', type=str, help='The directory containing the images')
args = parser.parse_args()
# Create output directory
output_dir = f"{args.dir}_shadow"
os.makedirs(output_dir, exist_ok=True)
# Process all PNG images in the directory
for filename in os.listdir(args.dir):
if filename.endswith(".png"):
full_path = os.path.join(args.dir, filename)
output_path = os.path.join(output_dir, filename)
# Extract multiplier from filename using regex
match = re.search(r"@(\d+)x", filename)
multiplier = int(match.group(1)) if match else 1
add_drop_shadow(full_path, output_path, multiplier=multiplier)
print(f"Added drop shadow to {filename}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment