Created
September 13, 2018 18:27
-
-
Save RichardMarks/327b54ba6e28c025e07b8ea67771b1f9 to your computer and use it in GitHub Desktop.
Python3 Image Crop Tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Image Crop Tool v1.0 | |
# (C) Rambling Indie Games, LLC | |
# Developed by Richard Marks <[email protected]> | |
# 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