Geek Culture
Published in

Geek Culture

Create Your Screenshots for the Stores With Python and PIL

I have published mobile apps for the play store and the app store. But formatting the screenshots for the stores is a long and boring task. You need to crop your screenshots, add a background and some text to highlight your keys feature. You have to repeat it for each different screen size. And do it again for all languages supported by your app.

So as a lazy developer I made a python script to automate these tasks and generate images ready to upload on the store.

The only package you will need to follow this article is Pillow or PIL. But I recommend not to use PIL since it’s not maintained.

For the first part of this article, I will use a screenshot of an iPhone emulator. And will focus on creating the image for a 6.5inch screen device, so I have to create a 1284 x 2778 image.

You can find all the devices size ask by Apple here

Open and show your screenshot

from PIL import Image

# Load your image
screenshot =
# Open a window to show it
# You can get the size of you image with
width, height = screenshot.size
The original screenshot

Crop the screenshot

Firstly we will remove the emulator’s toolbar

# The parameter is a tuple of fours numbers, defining the left, top, right, and bottom pixel coordinates. This box correspond to the image you want to keep
screenshot = screenshot.crop((0, 110, width, height))

I used 110 for the top value to remove 110 pixels from the top.

Screenshot without the toolbar

Add a Background

Let's create a background and add paste our screenshot on it. You could also load your own image or create a gradient.

store_width = 1284
store_height = 2778
width, height = screenshot.size

# Create an image with the desired size for the store
im ='RGBA', (store_width, store_height), color=(232, 106, 28))

# Paste the screenshot on the background and center it
im.paste(screenshot, (
int(store_width/2 - width/2),
int(store_height/2 - height/2)
), screenshot)
The screenshot on our wonderful orange background

Here is the code to make a vertical or a horizontal gradient:

Here is a gist on how to make a diagonal gradient:

Resize the image

Our screenshot seems a little small, so we will resize it before pasting it into a background.

def resize(im, ratio):
w, h = im.size
w = int(w * ratio)
h = int(h * ratio)
im = im.resize((w, h), Image.ANTIALIAS)
return im
screenshot = resize(screenshot, ratio=1.4)

Add a caption

This method creates a layer with text, and add it to our store image

You will have to give the path to a font file.

def add_text(im, text, font_path, font_size=120, text_color=(0, 0, 0)):
width, height = im.size

txt_image ='RGBA', (width, height), (0, 0, 0, 0))
font = ImageFont.truetype(font_path, font_size)
draw = ImageDraw.Draw(txt_image)
w, h = draw.textsize(text, font=font)

text_position = ((width-w)/2, 75)
draw.multiline_text(text_position, text, text_color, font=font, align="center")

im = Image.composite(im, txt_image, ImageChops.invert(txt_image))

return im
im = add_text(im, "My great caption", font_path=r'font/coolvetica condensed rg.ttf')

Structure & loop for each screenshot

I’ve organized my screenshot like this :

- English
- Android
- screenshot_1.png
- screenshot_2.png
- ...
- Ipad
- screenshot_1.png
- ...
- Iphone 5.5
- ...
- Iphone 6.5
- ...

- French
- ...
- Spanish
- ...
- ...

So we can loop over theses folders with the os package.

I’ve made two smalls functions. lisdir which will return all the files and folders for a given folder, except hidden ones (likes mac .DS_Store). And a save_screenshot method witch will save your image, and create folders if needed.

import os

def listdir(path):
return [f for f in os.listdir(path) if not f.startswith('.')]

def save_screenshot(img, path, file_name):
# Create folders
# Save image"{path}/{file_name}")

languages_folders = listdir(PATH)
# For every langagues
for languages_folder in languages_folders:
device_folders = listdir(f"{PATH}/{languages_folder}/")

# For every devices folders
for device_folder in device_folders:
# Get list of all the screenshot in the folder
screens = listdir(f"{PATH}/{languages_folder}/{device_folder}")

# For every screenshots
for screen in screens:
screenshot =

# Do our transformations on our screenshots
# You can also do some condition do some conditions, depending on the screenshot to ajuste size, caption ...
# Save the screenshot
save_screenshot(screenshot, PATH_OUTPUT_FOLDER, file_name=screen)

ScreenshotFormat package

I’ve made a package to wrap the differents methods we covered here. And added some other tools and helpers like different gradient background, help to positions images, adding text with halo, list all the different screenshot size required by apple …

Here is how it looks like:

from ScreenshotFormat import ScreenshotFormat, StoreSizeName, BackgroundType, PositionPATH_TO_YOUR_IMAGE = ""
# Instantiate the helper with our screenshot and the desired size for the store
helper = ScreenshotFormat(screenshot_path=PATH_TO_YOUR_IMAGE, store_size_name=StoreSizeName.iphone_6_5)

# Create an image, it will have the size of on iphone 6.5
background = helper.create_background(type_=BackgroundType.diagonal_gradient_right, color_palette=[
(255, 0, 0),
(255, 255, 0),
(255, 255, 255),

# Adding text
text_position = (, 150)
text = "My Caption"
background = helper.add_text_with_halo(background,
color=(0, 0, 0),
halo_col=(255, 255, 255),

# Adding screenshot on our background
position = (, helper.store_height - helper.screenshot_height - 100)
final_image = helper.apply_screenshot_on_background(background, position)

# Save image, path=OUTPUT_PATH, file_name="MyScreenshot.jpg")


Add a number at the beginning of the name of your screenshots, it will sort them automatically and will make the upload on the store much easier.

Thanks for reading




A new tech publication by Start it up (

Recommended from Medium

Practicing Domain Driven Design. Part 1: Understanding the problem.

Docker Container & Django Framework

Speed Coding and Blogging

Simple Dockerized gRPC Application with Envoy ext_authz Example

Distributed Job Scheduler — [Notes]

How to build an Event Pipeline Part 2: Transforming records using Lambda Functions

Joshnator: a one-stop package to clean and preprocess your text data for Natural Language…

An Introduction To Rust

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alexis Gomes

Alexis Gomes

I work at yper. I’m a python developer, learning data science. I’ve made a app

More from Medium

“Take Me Out to the Ball Game” Algorithmically Remastered in Python

JSON to 3D Model | Creating a Blender Tool

Proctoring Online Exams Using Artificial Intelligence Can Land You That Government Position: Remote…

Proctoring Online Exams Using Artificial Intelligence

How we are making a Video Game in Python #7