Skip to content

Instantly share code, notes, and snippets.

@yig
Last active May 22, 2017 01:18
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 yig/7770ec597c595ae4bf1d0de4ca5a65cf to your computer and use it in GitHub Desktop.
Save yig/7770ec597c595ae4bf1d0de4ca5a65cf to your computer and use it in GitHub Desktop.
Applies imagemagick's -trim to a set of images, but applies the same crop to all of them together (making sure to cut nothing untrimmable off from any)
#!/usr/bin/env python
'''
Author: Yotam Gingold <yotam (strudel) yotamgingold.com>
License: Public Domain [CC0](http://creativecommons.org/publicdomain/zero/1.0/)
Description: Applies imagemagick's -trim to a set of images, but applies the same crop to all of them together (making sure to cut nothing untrimmable off from any).
URL: https://gist.github.com/yig/7770ec597c595ae4bf1d0de4ca5a65cf
'''
from __future__ import print_function, division
import subprocess
import os, sys
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def usage():
eprint( "Applies imagemagick's -trim to a set of images, but applies the same crop to all of them together (making sure to cut nothing untrimmable off from any)." )
eprint( 'Usage:', sys.argv[0], "-suffix.png|--auto path/to/image1 path/to/image2 ..." )
sys.exit(-1)
if len( sys.argv ) < 2: usage()
suffix = sys.argv[1]
paths = sys.argv[2:]
if os.path.exists( suffix ):
eprint( "The first parameter should be a suffix or --auto. It exists as a file, which is probably an error." )
usage()
for image in paths:
if not os.path.exists( image ):
eprint( "File not found:", image )
usage()
top, left, right, bottom = None, None, None, None
## Gather outpaths
outpaths = []
for image in paths:
base, ext = os.path.splitext( image )
outpath = base + ( suffix if suffix != "--auto" else "-trim" + ext )
outpaths.append( outpath )
## Gather dimensions
for image, outpath in zip( paths, outpaths ):
output = subprocess.check_output( [ "convert", "-verbose", "-trim", image, outpath ], stderr = subprocess.STDOUT )
last_line = output.rstrip('\n').split('\n')[-1]
new_width, new_height = [ int(x) for x in last_line.split('=>')[-1].split()[0].split('x') ]
new_x, new_y = [ int(x) for x in last_line.split('=>')[-1].split()[1].split('+')[1:] ]
# print( "width:", new_width )
# print( "height:", new_height )
if top is None or new_y < top: top = new_y
if left is None or new_x < left: left = new_x
if bottom is None or new_y + new_height > bottom: bottom = new_y + new_height
if right is None or new_x + new_width > right: right = new_x + new_width
## Apply crop
crop_parameter = "%sx%s+%s+%s" % ( right-left, bottom-top, left, top )
for image, outpath in zip( paths, outpaths ):
command = [ "convert", "-crop", crop_parameter, image, outpath ]
print( ' '.join( command ) )
subprocess.check_output( command, stderr = subprocess.STDOUT )
print( "If you want to replace the original images, you may wish to follow up with a command like: rename -f -d '-trim' *-trim.png" )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment