import Image, ImageDraw, ImageFont import ImageEnhance, ImageOps, ImageStat def annotate(image, text, destination, font=None): """ Annotate an image with some text and save it to destination. - `image`: full path of source image, as a string - `text` : the string to paste on the image - `destination` : full path of image to save, as a string - `font` : full path of .pil bitmap font to use w <---------------------------> ^ +---------------------------+ | | | | | | | | | h | | (w0,h0) | | | +---------+ | | | |some text| | |-> hb | | +---------+(w1,h1) | |-> fromBottomPixels v +---------------------------+ l l <------> <-------> <---------> wb """ fromBottomPixels = 5 borderSize = 2 # Try to load a nice font (from pilfonts package) if font: font = ImageFont.load(font) else: font = ImageFont.load_default() img = Image.open(image) draw = ImageDraw.Draw(img) # calculate the textBox corners coordinates # text will be wrapped in that box wb, hb = font.getsize(text) w, h = img.size w0 = int((w-wb) / 2.) h0 = h - hb - fromBottomPixels w1 = w0 + wb h1 = h0 + hb box = (w0-borderSize, h0, w1+borderSize, h1) textBox = img.crop(box) inboundBox = Image.new('RGB', textBox.size, (136,213,123)) inboundBox = Image.blend(inboundBox, textBox, 0.5) # build the borders of the box size = inboundBox.size colour = (0, 0, 0) inboundBox = ImageOps.crop(inboundBox, border=borderSize) bordered = Image.new('RGBA', size, colour) bordered.paste(inboundBox, (borderSize, borderSize)) # paste the bordered box back to the image img.paste(bordered, box) # heh annotate the image, finally :) draw.text((w0,h0), text, font=font, fill=colour) img.save(destination) if __name__ == '__main__': import sys args = sys.argv[1:] if len(args) < 3: sys.exit(-1) if len(args) <= 4: image, text, destination = args[0:3] font = None if len(args) == 4: font = args[-1] annotate(image, text, destination, font)