Skip to content

Instantly share code, notes, and snippets.

@RichardMarks
Created September 13, 2018 18:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RichardMarks/327b54ba6e28c025e07b8ea67771b1f9 to your computer and use it in GitHub Desktop.
Save RichardMarks/327b54ba6e28c025e07b8ea67771b1f9 to your computer and use it in GitHub Desktop.
Python3 Image Crop Tool
#!/usr/bin/env python3
# Image Crop Tool v1.0
# (C) Rambling Indie Games, LLC
# Developed by Richard Marks <richard@ramblingindie.games>
# depends on Pillow third party library for PIL in Python 3.6
# pip3 install pillow
from PIL import Image
import json
import os
import sys
import glob
import pathlib
import time
def is_not_transparent(image, x, y):
pixel = image.getpixel((x, y))
if pixel[3] != 0:
return True
return False
def find_left_crop_coordinate(image, width, height):
for x in range(width):
for y in range(height):
if is_not_transparent(image, x, y):
return x
def find_top_crop_coordinate(image, width, height):
for y in range(height):
for x in range(width):
if is_not_transparent(image, x, y):
return y
def find_right_crop_coordinate(image, width, height):
for x in range(width - 1, -1, -1):
for y in range(height):
if is_not_transparent(image, x, y):
return x + 1
def find_bottom_crop_coordinate(image, width, height):
for y in range(height - 1, -1, -1):
for x in range(width):
if is_not_transparent(image, x, y):
return y + 1
def process_image(filename, output_path):
start_time = time.time()
image = Image.open(filename)
width, height = image.size
left_crop = find_left_crop_coordinate(image, width, height)
right_crop = find_right_crop_coordinate(image, width, height)
top_crop = find_top_crop_coordinate(image, width, height)
bottom_crop = find_bottom_crop_coordinate(image, width, height)
crop_width = right_crop - left_crop
crop_height = bottom_crop - top_crop
# print('filename:', filename)
# print('format:', image.format)
# print('mode:', image.mode)
# print('size:', str(width) + 'x' + str(height))
# print('crop size:', str(crop_width) + 'x' + str(crop_height))
# print('x offset:', left_crop)
# print('y offset:', top_crop)
cropped_image = image.crop((
left_crop,
top_crop,
right_crop,
bottom_crop
))
base, ext = os.path.splitext(os.path.basename(filename))
# print('base:', base)
# print('ext:', ext)
# print('basename', os.path.basename(filename))
crop_filename = base + '_crop.png'
cropped_image.save(os.path.join(output_path, crop_filename), 'PNG')
image_data = {
'id': base,
'filename': crop_filename,
'width': crop_width,
'height': crop_height,
'x': left_crop,
'y': top_crop
}
end_time = time.time()
process_time = end_time - start_time
print("Processed %s (%.2fs)" % (filename, process_time))
return image_data
def main():
# scriptname [source-path] [output-path]
source_path = './*.png'
output_path = './output'
if len(sys.argv) > 1:
source_path = os.path.join(sys.argv[1], '*.png')
if len(sys.argv) > 2:
output_path = sys.argv[2]
print('source path:', source_path)
print('output path:', output_path)
pathlib.Path(output_path).mkdir(parents=True, exist_ok=True)
data = {}
data['meta'] = {}
data['meta']['version'] = '1.0.0'
data['images'] = []
for filename in glob.glob(source_path):
data['images'].append(
process_image(filename, output_path)
)
with open(os.path.join(output_path, 'images.json'), 'w') as outfile:
json.dump(data, outfile, indent=2)
if __name__ == "__main__":
start_time = time.time()
main()
print("--- Finished in %.2fs ---" % (time.time() - start_time))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment