How to check dimensions of all images in a directory using python?
Solution 1:
If you don't need the rest of PIL and just want image dimensions of PNG, JPEG and GIF then this small function (BSD license) does the job nicely:
http://code.google.com/p/bfg-pages/source/browse/trunk/pages/getimageinfo.py
import StringIO
import struct
def getImageInfo(data):
data = str(data)
size = len(data)
height = -1
width = -1
content_type = ''
# handle GIFs
if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
# Check to see if content_type is correct
content_type = 'image/gif'
w, h = struct.unpack("<HH", data[6:10])
width = int(w)
height = int(h)
# See PNG 2. Edition spec (http://www.w3.org/TR/PNG/)
# Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
# and finally the 4-byte width, height
elif ((size >= 24) and data.startswith('\211PNG\r\n\032\n')
and (data[12:16] == 'IHDR')):
content_type = 'image/png'
w, h = struct.unpack(">LL", data[16:24])
width = int(w)
height = int(h)
# Maybe this is for an older PNG version.
elif (size >= 16) and data.startswith('\211PNG\r\n\032\n'):
# Check to see if we have the right content type
content_type = 'image/png'
w, h = struct.unpack(">LL", data[8:16])
width = int(w)
height = int(h)
# handle JPEGs
elif (size >= 2) and data.startswith('\377\330'):
content_type = 'image/jpeg'
jpeg = StringIO.StringIO(data)
jpeg.read(2)
b = jpeg.read(1)
try:
while (b and ord(b) != 0xDA):
while (ord(b) != 0xFF): b = jpeg.read(1)
while (ord(b) == 0xFF): b = jpeg.read(1)
if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
jpeg.read(3)
h, w = struct.unpack(">HH", jpeg.read(4))
break
else:
jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
b = jpeg.read(1)
width = int(w)
height = int(h)
except struct.error:
pass
except ValueError:
pass
return content_type, width, height
Solution 2:
One common way is to use PIL, the python imaging library to get the dimensions:
from PIL import Image
import os.path
filename = os.path.join('path', 'to', 'image', 'file')
img = Image.open(filename)
print img.size
Then you need to loop over the files in your directory, check the dimensions against your required dimensions, and move those files that do not match.
Solution 3:
You can use the Python Imaging Library (aka PIL) to read the image headers and query the dimensions.
One way to approach it would be to write yourself a function that takes a filename and returns the dimensions (using PIL). Then use the os.path.walk
function to traverse all the files in the directory, applying this function. Collecting the results, you can build a dictionary of mappings filename -> dimensions
, then use a list comprehension (see itertools
) to filter out those that do not match the required size.
Solution 4:
Here is a script that does what you need:
#!/usr/bin/env python
"""
Get information about images in a folder.
"""
from os import listdir
from os.path import isfile, join
from PIL import Image
def print_data(data):
"""
Parameters
----------
data : dict
"""
for k, v in data.items():
print("%s:\t%s" % (k, v))
print("Min width: %i" % data["min_width"])
print("Max width: %i" % data["max_width"])
print("Min height: %i" % data["min_height"])
print("Max height: %i" % data["max_height"])
def main(path):
"""
Parameters
----------
path : str
Path where to look for image files.
"""
onlyfiles = [f for f in listdir(path) if isfile(join(path, f))]
# Filter files by extension
onlyfiles = [f for f in onlyfiles if f.endswith(".jpg")]
data = {}
data["images_count"] = len(onlyfiles)
data["min_width"] = 10 ** 100 # No image will be bigger than that
data["max_width"] = 0
data["min_height"] = 10 ** 100 # No image will be bigger than that
data["max_height"] = 0
for filename in onlyfiles:
im = Image.open(filename)
width, height = im.size
data["min_width"] = min(width, data["min_width"])
data["max_width"] = max(width, data["max_width"])
data["min_height"] = min(height, data["min_height"])
data["max_height"] = max(height, data["max_height"])
print_data(data)
if __name__ == "__main__":
main(path=".")