I've very much a noob when it comes to image processing :( I have a bunch of PNG files (300 of them) that have large areas of transparency that I wish to crop. I want to automate the process obviously, hence why i tried using python and PIL.
Now I have a look at the following link, Crop a PNG image to its minimum size, and also using Numpy as suggested by this link, Automatically cropping an image with python/PIL, both to no success :( The output files are identical to the input files! no cropping of the transparency, same size. The getbbox is returning same width and height.
Here's a link to one of those images; 98x50button The image is of a button icon in the shape of a bell. it's drawn in white so it's hard to see which transparent background. The expected outcome would a 20x17 Button (with the transparency inside that 20x17 box remaining in tact)
Here's the code i'm using;
#!/usr/bin/env python
import sys
import os
import Image
import numpy as np
def autocrop_image2(image):
image.load()
image_data = np.asarray(image)
image_data_bw = image_data.max(axis=2)
non_empty_columns = np.where(image_data_bw.max(axis=0) > 0)[0]
non_empty_rows = np.where(image_data_bw.max(axis=1) > 0)[0]
cropBox = (min(non_empty_rows), max(non_empty_rows),
min(non_empty_columns), max(non_empty_columns))
image_data_new = image_data[cropBox[0]:cropBox[
1] + 1, cropBox[2]:cropBox[3] + 1, :]
new_image = Image.fromarray(image_data_new)
return new_image
def autocrop_image(image, border=0):
# Get the bounding box
bbox = image.getbbox()
# Crop the image to the contents of the bounding box
image = image.crop(bbox)
# Determine the width and height of the cropped image
(width, height) = image.size
# Add border
width += border * 2
height += border * 2
# Create a new image object for the output image
cropped_image = Image.new("RGBA", (width, height), (0, 0, 0, 0))
# Paste the cropped image onto the new image
cropped_image.paste(image, (border, border))
# Done!
return cropped_image
walk_dir = sys.argv[1]
print('walk_dir = ' + walk_dir)
# If your current working directory may change during script execution, it's recommended to
# immediately convert program arguments to an absolute path. Then the variable root below will
# be an absolute path as well. Example:
# walk_dir = os.path.abspath(walk_dir)
print('walk_dir (absolute) = ' + os.path.abspath(walk_dir))
for root, subdirs, files in os.walk(walk_dir):
print('--\nroot = ' + root)
list_file_path = os.path.join(root, 'my-directory-list.txt')
print('list_file_path = ' + list_file_path)
with open(list_file_path, 'wb') as list_file:
for subdir in subdirs:
print('\t- subdirectory ' + subdir)
for filename in files:
file_path = os.path.join(root, filename)
print('\t- file %s (full path: %s)' % (filename, file_path))
filename, file_extension = os.path.splitext(filename)
if file_extension.lower().endswith('.png'):
# Open the input image
image = Image.open(file_path)
# Do the cropping
# image = autocrop_image(image, 0)
new_image = autocrop_image2(image)
# Save the output image
output = os.path.join("output", filename + ".png")
print output
new_image.save(output)
Thank you all for the help :)