Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ## thumbnailarray.py
- ##
- ## coded by cogs [cogs@springlessclock.com]
- ## 2012.02.05
- ## This is just meant as an example of the different options
- ## available for resizing images in python.
- ## Calling this from the command line;
- ## >> python thumbnailarray.py [-w WIDTH] [-h HEIGHT] [-o OUTFILE] INFILE
- ## If you only pass in one of width or height then the image will be
- ## resized and try to maintain the aspect ratio, if neither is passed
- ## it will default to a height of 100px.
- ##
- ## Though this was originally written as a way to see how each algorithm
- ## would produce a thumbnail, it can be used to test whatever, up-scaling,
- ## down-scaling... that's about it. Feel free to use this or hack apart parts
- ## you want, I've included notes in the appropriate functions for where I
- ## found different algorithms.
- ##
- ## This is able to grab an image from a url, as well as from your
- ## file system, and save to a file you specify. If no file is specified,
- ## it will use the original file name for the base file. Don't worry, it will
- ## not overwrite the original file, it appends a string for each resize
- ## example. Use --help if you need more info; there's not a whole lot to it.
- ## This is set up to take only one image for simplicity's sake, but if you need
- ## bulk processing you should probably just cannibalize what you need, anyhow.
- ##
- ## PACKAGES YOU'LL NEED:
- ## - numpy : http://numpy.scipy.org/
- ## - PIL : http://www.pythonware.com/products/pil/
- ##
- ## This was written on python 2.7, it has not been tested for anything else.
- ##
- ## Happy coding! -cogs
- import numpy, Image, ImageFile, os, urllib2, argparse, sys
- from urlparse import urlparse
- def getImg(filename):
- """
- This function will retrive the image at the specified file
- name. It has some minor checking to see if it is on the
- internet, and will read it via urllib2, but otherwise
- assumes it is local. This returns a tuple, containing
- the (image, path_to_file, filename). If this is a
- url, the path_to_file will be an empty string.
- """
- loc = urlparse(filename)
- if loc.scheme == '':
- # the file is assumed to be local
- fpath,fname = os.path.split(filename)
- try:
- return Image.open(filename),fpath,fname
- except IOError:
- print "Unable to open file %s" % filename
- return False,fpath,fname
- else:
- # the file is assumed to be online
- try:
- _,fname = os.path.split(loc.path)
- instr = urllib2.urlopen(filename)
- parser = ImageFile.Parser()
- parser.feed(instr.read())
- img = parser.close()
- return img,'',fname
- except:
- print "Unable to retrieve file %f" % filename
- return False,'',''
- def premult(img):
- """
- Credit for this function goes to madlag on stackoverflow,
- as found here:
- http://stackoverflow.com/a/6882161/1189554
- """
- im = img.convert('RGBA')
- premult = numpy.fromstring(im.tostring(), dtype=numpy.uint8)
- alphaLayer = premult[3::4] / 255.0 # gets the alpha channel
- premult[::4] *= alphaLayer
- premult[1::4] *= alphaLayer
- premult[2::4] *= alphaLayer
- return Image.fromstring('RGBA', im.size, premult.tostring())
- def resize(img,size,resamp):
- """
- Just calls the resize method in the PIL library with the
- provided resampling type
- """
- return img.resize(size,resamp)
- def noalpha(img,size,resamp):
- """
- This removes the alpha channel from the image then resizes
- it.
- """
- newimg = img.convert('RGB')
- return resize(newimg,size,resamp)
- def doubleresize(img,size,resamp):
- """
- This method was suggested here:
- http://united-coders.com/christian-harms/image-resizing-tips-general-and-for-python
- And involves resizing to double your final size, first with
- the fastest algorithm you have (nearest neighbor, usually)
- and then down using the best algorithm you have. Here
- "resamp" is the final algorithm used.
- """
- doublesize = (size[0] * 2,size[1] * 2)
- newimg = img.resize(doublesize)
- return resize(newimg,size,resamp)
- def premultresize(img,size,resamp):
- """
- This is just to help out and make the main method more readable;
- will call the premult method then the resize method with the
- appropriate resampling type
- """
- newimg = premult(img)
- return resize(newimg,size,resamp)
- def resizearray(filename, size, outfile = None):
- """
- resizeimg will call each of the resize functions and
- save the result.
- """
- img,fpath,fname = getImg(filename)
- if outfile is not None:
- fpath, oname = os.path.split(outfile)
- if oname != '.' and oname != '':
- fname = oname
- if not img:
- return
- width, height = size
- if width is None and height is None:
- height = 100
- # do some basic calculation to find what the missing side,
- # if any, should be
- origwidth, origheight = img.size
- if width is None and height is not None:
- width = int(origwidth * (height / float(origheight)))
- elif height is None and width is not None:
- height = int(origheight * (width / float(origwidth)))
- newsize = (width, height)
- # this covers all of the standard resize interpolations
- # supported by PIL, as well as two extra that were
- # suggested. The tuples are in the order:
- # 1. Name to be prepended to the output file
- # 2. Function to call. Function should have the
- # signature: Image func(Image, (height,width), Image.ENUM)
- # 3. One of the enumerated resampling algorithms. Options are:
- # Image. NEAREST, BILINEAR, BICUBIC, ANTIALIAS
- rearray = [
- ('NEAREST', resize, Image.NEAREST),
- ('BILINEAR', resize, Image.BILINEAR),
- ('BICUBIC', resize, Image.BICUBIC),
- ('ANTIALIAS', resize, Image.ANTIALIAS),
- ('DOUBLE', doubleresize, Image.ANTIALIAS),
- ('PREMULT', premultresize, Image.ANTIALIAS),
- ('NOALPHA', noalpha, Image.ANTIALIAS),
- ]
- for sampletype, funct, resamp in rearray:
- newimg = funct(img,newsize,resamp)
- saveloc = os.path.join(fpath,sampletype + '_' + fname)
- try:
- newimg.save('%s' % saveloc)
- except:
- print 'Unable to save %(path)s%(type)s_%(fname)s' % {
- 'path': fpath + os.sep,
- 'type': sampletype,
- 'fname': fname}
- def main(*args):
- parser = argparse.ArgumentParser(description="Create thumbnails of a file")
- parser.add_argument('filename', metavar='F', type=str, nargs=1,
- help='The filename to parse')
- parser.add_argument('-W','--width', dest='width', metavar='W', type=int,
- default=None, action='store',
- help='The desired width of the thumbnail')
- parser.add_argument('-H','--height', dest='height', metavar='H', type=int,
- default=None, action='store',
- help='The desired height of the thumbnail')
- parser.add_argument('-o','--outfile', dest='outfile', metavar='O', type=str,
- default=None, action='store',
- help='The base filename to write to')
- parsed = parser.parse_args()
- try:
- size = (parsed.width, parsed.height)
- oname = parsed.outfile
- fname = parsed.filename
- for readfile in fname:
- resizearray(readfile,size,oname)
- except:
- print "Something went wrong"
- return 1
- else:
- return 0
- if __name__ == "__main__":
- sys.exit(main(*sys.argv))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement