Skip to content

Instantly share code, notes, and snippets.

@jkctech
Last active June 10, 2024 01:43
Show Gist options
  • Save jkctech/4c4820cdb504230ef1aeca09836e4452 to your computer and use it in GitHub Desktop.
Save jkctech/4c4820cdb504230ef1aeca09836e4452 to your computer and use it in GitHub Desktop.
Automatic screenshot cropper for mobile screenshots on social media.

Auto Cropper

A small snippet that crops screenshots from social media platforms like Instagram to only contain the picture. This is done by looking for the first row / column on the top / bottom / top / left of the screen (Starting from the center) where all pixels are the same color. This -usually- marks the end of a picture.

This tool is NOT perfect and compression algorithms like JPEG might mess up the working of this tool. It's more of a "Best guess" method.

  1. Install "PIL" for Python: python -m pip install Pillow
  2. Use cropper by one of 2 ways: 2a. In a terminal: python cropy.py /path/to/folder 2b. Drag folder on top of crop.py
  3. Files will be saved in new folder cropped inside source folder.

example

from os import walk, path
from PIL import Image
from sys import argv
from pathlib import Path
# Infolder
if len(argv) > 1:
infolder = argv[1]
if infolder[-1] != "/":
infolder += "/"
else:
print("Please provide a folder to crop!")
exit(1)
# Outfolder
if len(argv) > 2:
outfolder = argv[2]
if outfolder[-1] != "/":
outfolder += "/"
else:
outfolder = infolder + "cropped/"
# Check infolder
if not path.exists(infolder) or not path.isdir(infolder):
print("Invalid input folder!")
exit(1)
# Make outfolder
Path(outfolder).mkdir(parents=True, exist_ok=True)
# Load in all files
print("Reading from", infolder)
print("Saving in", outfolder)
files = next(walk(infolder), (None, None, []))[2]
print("Found {} files!".format(len(files)))
print("=" * 20)
# TOP
def line_top(pix, center, width):
for y in range(center[1], -1, -1):
c = pix[0, y]
for x in range(1, width):
if pix[x, y] != c:
break
if x == width - 1:
return y
return 0
# BOTTOM
def line_bottom(pix, center, width, height):
for y in range(center[1], height):
c = pix[0, y]
for x in range(1, width):
if pix[x, y] != c:
break
if x == width - 1:
return y
return height
# LEFT
def line_left(pix, center, height):
for x in range(center[0], -1, -1):
c = pix[x, 0]
for y in range(1, height):
if pix[x, y] != c:
break
if y == height - 1:
return x
return 0
# RIGHT
def line_right(pix, center, width, height):
for x in range(center[0], width):
c = pix[x, 0]
for y in range(1, height):
if pix[x, y] != c:
break
if y == height - 1:
return x
return width
# Loop over all files
for fname in files:
# Setup paths
infile = infolder + fname
fdata = path.splitext(fname)
outfile = outfolder + fdata[0] + "_cropped" + fdata[1]
print("Reading {}...".format(infile))
# Skip if exists
if path.exists(outfile):
print("Skipped!")
continue
# Load image and values into memory
img = Image.open(infile)
pix = img.load()
width, height = img.size
center = (int(width / 2), int(height / 2))
if width > 1 and height > 1:
# First calc top & bottom
bottom = line_bottom(pix, center, width, height)
top = line_top(pix, center, width)
# Crop and reload
img = img.crop((0, top, width, bottom))
pix = img.load()
width, height = img.size
center = (int(width / 2), int(height / 2))
# Calc left & right
left = line_left(pix, center, height)
right = line_right(pix, center, width, height)
# Crop second time
img = img.crop((left, 0, right, height))
# Export
print("Saving {}...".format(outfile))
img.save(outfile)
print("=" * 20)
print("Complete!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment