#!/usr/bin/env python # tile-photos # a Gimp plug-in # by Jaromir Malenko # homepage http://www.ms.mff.cuni.cz/~malej9am/prog/gimp/tile-photos # licence GPL-2 # Changelog: # 2005-01-24 # Created # 2005-04-03 # Publicly available #### Init #### import inspect import pprint import string import math from gimpfu import * def adjust(total, num, skip, left, right, img, dir): if num == -1: if total == -1: if dir == 'horizontal': s = ('columns', 'width') else: s = ('rows', 'height') gimp.message('You must set number of %s or image %s.' % s) return if skip >= 0 and left >= 0: if right >= 0: num = int((total - left - right + skip) / (img + skip)) ; print 'num = %i' % num else: num = int((total - 2*left + skip) / (img + skip)) ; print 'num = %i' % num elif skip >= 0: if right >= 0: num = int((total - right + skip) / (img + skip)) ; print 'num = %i' % num left = img - num * img - (num-1) * skip - right ; print 'left = %i' % left else: num = int((total + skip) / (img + skip)) ; print 'num = %i' % num left = int((total - num * img - (num-1) * skip) / 2) ; print 'left = %i' % left right = left ; print 'right = %i' % right elif left >= 0: num = int((total - left - right) / img) ; print 'num = %i' % num skip = int((total - left - right) / (num-1)) ; print 'skip = %i' % skip else: if right >= 0: num = int((total - right) / img) ; print 'num = %i' % num left = int((total - right - num * img) / (num+1)) ; print 'left = %i' % left skip = left ; print 'skip = %i' % skip else: num = int(total / img) ; print 'num = %i' % num left = int((total - num * img) / (num+1)) ; print 'left = %i' % left right = left ; print 'right = %i' % right skip = left ; print 'skip = %i' % skip else: if total == -1: if skip == -1 and left == -1: #print "If you don't set img, you must set space to skip in row and left border. Setting them to 0." total = num*img ; print 'total = %i' % total skip = 0 ; print 'skip = %i' % skip left = 0 ; print 'left = %i' % left right = 0 ; print 'right = %i' % right elif skip == -1: skip = left ; print 'skip = %i' % skip elif left == -1: left = skip ; print 'left = %i' % left if right == -1: right = left ; print 'right = %i' % right total = left + num * img + (num-1) * skip + right ; print 'total = %i' % total else: if skip == -1 and left == -1: skip = (total - num * img) / (num+1) ; print 'skip = %i' % skip left = skip ; print 'left = %i' % left if right == -1: right = left ; print 'right = %i' % right elif skip == -1: skip = (total - num * img - left - right) / (num-1) ; print 'skip = %i' % skip elif left == -1: if right == -1: left = (total - num * img - (num-1) * skip) / 2 ; print 'left = %i' % left right = left ; print 'right = %i' % right else: left = total - num * img - (num-1) * skip - right ; print 'left = %i' % left elif total != left + num * img + (num-1) * skip + right: if dir == 'horizontal': s = ('width', 'columns', 'columns', 'left', 'right', 'width') else: s = ('height', 'rows', 'rows', 'top', 'bottom', 'height') print "The %s of image doesn't match the number of %s, space between %s and %s and %s border. Correcting imgage %s." % s total = left + num * img + (num-1) * skip + right ; print 'total = %i' % total return (total, num, skip, left, right) #### The Python-Fu function itself #### def python_tile_photos(image, drawable, rows=-1, cols=-1, img_paper = 0, img_orientation=0, img_dpi=300, img_width=-1, img_height=-1, skip_col=-1, skip_row=-1, border_top=-1, border_bottom=-1, border_left=-1, border_right=-1): print 'Starting tile-photos plug-in' image.disable_undo() gimp.progress_init("Tile photos") progress_increment = 1 / (rows * cols) progress = 0.0 gimp.progress_update(progress) # Recalculate spaces and dimensions # adjust page size if img_paper != 0: (h, w) = string.split(img_paper, 'x') img_width = int(float(w) / 25.4 * img_dpi) img_height = int(float(h) / 25.4 * img_dpi) if img_orientation == 0: i = img_height img_height = img_width img_width = i # adjust borders if border_right == -1: border_right = border_left if border_bottom == -1: border_bottom = border_top print 'HORIZONTAL' (img_width, cols, skip_col, border_left, border_right) = adjust(img_width, cols, skip_col, border_left, border_right, image.width, 'horizontal') print 'VERTICAL' (img_height, rows, skip_row, border_top, border_bottom) = adjust(img_height, rows, skip_row, border_top, border_bottom, image.height, 'vertical') print 'rows=%i cols=%i paper=%s orientation=%i width=%i height=%i skip_row=%i skip_col=%i border top=%i bottom=%i left=%i right=%i' % (rows, cols, img_paper, img_orientation, img_width, img_height, skip_row, skip_col, border_top, border_bottom, border_left, border_right) # create background layer img = gimp.Image(img_width, img_height, RGB) img.disable_undo() layer_bg = gimp.Layer(img, 'Background', img.width, img.height, RGB_IMAGE, 100, NORMAL_MODE) pdb.gimp_drawable_fill(layer_bg, BACKGROUND_FILL) img.add_layer(layer_bg, 0) pdb.gimp_selection_all(image) for r in range(rows): for c in range(cols): # create new layer layer = gimp.Layer(img, 'Photo %sx%s' % (c, r), image.width, image.height, RGB_IMAGE, 100, NORMAL_MODE) pdb.gimp_drawable_fill(layer, BACKGROUND_FILL) img.add_layer(layer, 0) layer.set_offsets(border_left + c * image.width + c * skip_col, border_top + r * image.height + r * skip_row) # copy original image to layer pdb.gimp_edit_copy(image.active_layer) floatingLayer= pdb.gimp_edit_paste(layer, 1) pdb.gimp_floating_sel_anchor(floatingLayer) layer.flush() progress += progress_increment gimp.progress_update(progress) pdb.gimp_selection_none(image) img.active_layer = layer_bg disp = gimp.Display(img) img.enable_undo() image.enable_undo() print 'End of tile-photos plug-in' #### Plugin initialization #### register( 'python_fu_tile_photos', # name 'Tile photos to image', # blurb '''Tile photos to a large image. Useful for printing your own passport-size photos. 1. Open a photo. 2. Change the DPI to 300 (menu Image -> Scale image: Resolution X, Y). 3. Optional: Change the size of photo (menu Image -> Scale image: New width, height). 2. Run this script. A new image is created with tiled photos. You can set many variables such space between photos, size of borders, size of paper (or exactly size of image in pixels) and paper orientation. ''', # help 'Jaromir Malenko', # author 'Jaromir Malenko', # copyright '2005', # date '/Python-Fu/Tile photo', # menupath '*', # imagetypes [ # params (PF_INT, 'rows', 'Number of rows\n-1 for auto (fit to paper size)', -1), (PF_INT, 'cols', 'Number of columns\n-1 for auto (fit to paper size)', -1), (PF_RADIO, "img_paper", "Size of paper", 0, # size in milimeters, source: http://www.cl.cam.ac.uk/~mgk25/iso-paper.html (('Custom', 0), ('A3', '297x420'), ('A4', '210x297'), ('A5', '148x210'), ('A6', '105x148'), ('Letter', '216x279'), ('Legal', '216x356'), ('Executive', '190x254'), ('Ledger/Tabloid', '279x432'), ('9x13 cm', '90x130'), ('10x15 cm', '100x150'), ('Auto (by boders and spaces between photos)', 2) )), (PF_RADIO,'img_orientation', 'Orientation', 0, ( ('Portrait', 0), ('Landscape', 1) )), (PF_INT, 'img_dpi', 'Image DPI\n', 300), (PF_INT, 'img_width', 'Image width (in px)\nOnly for custom paper size\n-1 for auto', -1), (PF_INT, 'img_height', 'Image height (in px)\nOnly for custom paper size\n-1 for auto', -1), (PF_INT, 'skip_col', 'Space between colums\n-1 for auto', -1), (PF_INT, 'skip_row', 'Space between rows\n-1 for auto', -1), (PF_INT, 'border_top', 'Top border\n-1 for auto', -1), (PF_INT, 'border_bottom', 'Bottom border\n-1 for auto', -1), (PF_INT, 'border_left', 'Left border\n-1 for auto', -1), (PF_INT, 'border_right', 'Right border\n-1 for auto', -1) ], [], # results python_tile_photos) # function main() # vim:set ts=4 sw=4 sts=4: