Sunday, September 23, 2012

PIL Introduction, Batch Image Converting

PIL or the Python Imaging Library, is a library designed to add imaging processing capabilities to python. PIL supports a variety of image formats including: PNG, JPEG, TIFF, as well as many others.

Note: The examples here apply to Python 2.7 and PIL 1.1.7

To open an image using PIL, we use the PIL's Image module (in an interactive shell, or python script):
>>> from PIL import Image
>>> im=Image.open('./example.JPG')
Where './example.JPG' is the image path. This creates an PIL instance of the specified image, im.

There are some useful attributes of the image class such as:
>>> im.size
(3872, 2592)
>>> im.format
'JPEG'
>>> im.mode
'RGB'

We can now use this instance to do a variety of tasks such as showing the image:
>>> im.show()

Rotating the  image counter clockwise at an angle specified  in degrees, creating a new image instance of the rotated image:
>>> im2=im.rotate(45)

Re-sizing the image, preserving the aspect ratio:
>>> im.thumbnail([128,128])
This will re-size the maximum dimension, preserving the aspect ratio. To control the interpolation scheme of the re-size, you can pass a filter argument such as NEARESTBILINEARBICUBIC, or ANTIALIAS (the best quality):
>>> im.thumbnail([128,128],Image.ANTIALIAS)

Re-sizing the image, not preserving the aspect ratio:
>>> im.resize([128,128])
You can also change the interpolation scheme:
>>> im.resize([128,128],Image.ANTIALIAS)

Cropping the image by providing a cropping box in terms of (Left, Upper, Right, Lower) in terms of pixels, this also returns a new image instance:
>>> im3=im.crop([10,40,400,350])

Finally, saving the resulting image as jpeg (indicated by the file extension):
>>> im.save('./exampleOut.jpg')
You may also explicitly tell the function what format to save it in (int his case, as png image):
>>> im.save('./exampleOut', 'PNG')
Note: This will not automatically append the file extension to the file name.

Bringing these concepts together along with some core python functions, we can write a simple script (i.e. batchImgConvert.py) to convert all the *.jpg files in a giving folder to *.png files:
#import require libraries
from PIL import Image
import glob
import os

# Find all the jpegs in a given folder: folder='C:/exampleImages/' imList=glob.glob(folder+'*.jpg')
# Loop through all the image: for img in imList: # open the image im = Image.open(img) # extract the filename and extension from path fileName, fileExt = os.path.splitext(img) # save the image in the same folder, with the same name, except *.png im.save(folder+fileName+'.png')

Once you have this mastered, then the sky is the limit. You can use the commands described above to batch rotate, resize, and crop. There are many more functions available in PIL, which will be covered later.

To give you a more complex example that I used to answer a question on the photography stack exchange:

#Python 2.7, PIL 1.1.7

import Image
import glob
import os

#Function to resize image, preserving aspect ratio
def resizeAspect(im, size):
    w,h = im.size
    aspect=min(size[0]/float(w), size[1]/float(h))
    return im.resize((int(w*aspect),int(h*aspect)),Image.ANTIALIAS)

#Find all png images in a directory
imgList=glob.glob('C:/icons/*.png')         

#Loop through all found images
for img in imgList:
    #open the image                           
    im = Image.open(img)                        
    print "resizing:",os.path.basename(img)
    #Get image width and height
    w,h = im.size    
    
    #Check if either dimension is smaller then 600                           
    if min(w,h)<600:
        #Re-size Image                  
        im=resizeAspect(im,(600,600))
        #update image size          
        w,h = im.size

    #Calculate Center                     
    center = [int(w/2.0),int(h/2.0)]
    #Defines a box where you want it to be cropped  
    box = (center[0]-300, center[1]-300, center[0]+300, center[1]+300)
    #Crop the image
    croppedIm = im.crop(box)                                
    fileName, fileExtension=os.path.splitext(img)
     #Save the cropped image
    croppedIm.save(fileName+'_crop.png', "PNG")



No comments:

Post a Comment