You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
4.9 KiB
Python
109 lines
4.9 KiB
Python
#! /usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
import os, tempfile, shlex, subprocess
|
|
from argparse import ArgumentParser
|
|
from random import shuffle
|
|
|
|
####
|
|
# Arguments
|
|
# TODO: add example to description
|
|
####
|
|
p = ArgumentParser(description='Script converts 8 images (jpg or png) from a given directory into a single page 4x2 imposition. Example: python imposition.py --dir imgs/ --size a3 --order random ')
|
|
p.add_argument("--dir", metavar='', default='imgs', required=True, help="Image directory, which stores the source images for the imposition")
|
|
p.add_argument("--size", metavar='', default="A4", choices=['A4','a4','A3','a3'], help="Size of the printing sheet: A4 or A3. Default:A4")
|
|
p.add_argument("--pages", metavar='', type=int, choices=[1,2], default=1, help="Number of imposition pages. Default:1. Currently only 1 or 2 pages impositions are available.")
|
|
p.add_argument("--order", metavar='', default="alphabet", choices=["alphabet", "reverse", "random"], help="Image distribution Order in the imposition. Possible Values: alphabet (alphabetically) , reverse (reverse alphabetically), random. Default: alphabet")
|
|
p.add_argument("--output", metavar='' ,default="output.pdf", help="Output file. Can either be a pdf, jpg or png. Default: output.pdf")
|
|
args = p.parse_args()
|
|
print args
|
|
temp_dir = tempfile.mkdtemp()
|
|
|
|
# dimensions
|
|
args.size = (args.size).upper()
|
|
global size_sheet
|
|
if args.size == 'A4':
|
|
size_sheet = (3508, 2480) #landscape: widthxheight in px
|
|
elif args.size == 'A3':
|
|
size_sheet = (4960, 3508) #landscape: widthxheight in px
|
|
size_pages = (size_sheet[0]/4,size_sheet[1]/2 )# size of each of the pages which makes up the printing sheet
|
|
|
|
# image selection
|
|
listdir = os.listdir( os.path.abspath(args.dir))
|
|
listdir = [f for f in listdir if any (x in f for x in ['.jpeg','.jpg','.png','.JPEG','.JPG','.PNG', '.Jpg', '.Jpeg','.Png']) ] #only bitmaps allowed
|
|
|
|
# create list of 8 ordered images
|
|
global listdir_order
|
|
if args.order == 'alphabet':
|
|
listdir.sort()
|
|
listdir_order = listdir
|
|
elif args.order == 'reverse':
|
|
listdir.sort()
|
|
listdir.reverse()
|
|
listdir_order = listdir
|
|
elif args.order == 'random':
|
|
shuffle(listdir)
|
|
listdir_order = listdir
|
|
|
|
# print listdir_order
|
|
if args.pages == 1:
|
|
listdir_order = listdir_order[0:8]
|
|
pagenumbers = [2,5,4,3,1,6,7,0] # from from top left to bottom right ( order in imagemagick creates mosaic)
|
|
elif args.pages == 2:
|
|
listdir_order = listdir_order[0:16]
|
|
pagenumbers = [4,11,8,7,3,12,15,0,6,9,10,5,1,14,13,2]
|
|
|
|
listdir_order = [listdir_order[n] for n in pagenumbers] # reorder files according to pagenumbers
|
|
print 'selected files according to pagenumbers:', listdir_order
|
|
|
|
# image conversion: -extent
|
|
tmpfiles = [ (temp_dir +'/'+ str(n)+'.jpg') for n, img in enumerate(listdir_order) ]
|
|
for n, img in enumerate(listdir_order):
|
|
template_convert = 'convert -background white "{targetimg}" -gravity Center -resize {w}x{h} -extent {w}x{h} {tmpfile}'
|
|
cmd_convert = template_convert.format(targetimg=(os.path.abspath(args.dir))+'/'+img,
|
|
w=size_pages[0],
|
|
h=size_pages[1],
|
|
tmpfile=tmpfiles[n])
|
|
cmd_convert_l = shlex.split(cmd_convert)
|
|
subprocess.call(cmd_convert_l)
|
|
|
|
# # montage
|
|
tmp_output = (temp_dir +'/'+'output.jpg')
|
|
|
|
if args.pages == 1:
|
|
template_montage = "montage -geometry +1+1 -tile 4x2 \( -rotate 180 {topfiles_p1} \) {bottomfiles_p1} {output}"
|
|
cmd_montage = template_montage.format(
|
|
topfiles_p1=' '.join(tmpfiles[:4]),
|
|
bottomfiles_p1=' '.join(tmpfiles[4:8]),
|
|
output = tmp_output)
|
|
elif args.pages == 2:
|
|
template_montage = "montage -geometry +1+1 -tile 4x2 \( -rotate 180 {topfiles_p1} \) {bottomfiles_p1} \( -rotate 180 {topfiles_p2} \) {bottomfiles_p2} {output}"
|
|
cmd_montage = template_montage.format(
|
|
topfiles_p1=' '.join(tmpfiles[:4]),
|
|
bottomfiles_p1=' '.join(tmpfiles[4:8]),
|
|
topfiles_p2=' '.join(tmpfiles[8:12]),
|
|
bottomfiles_p2=' '.join(tmpfiles[12:]), output = tmp_output)
|
|
|
|
print 'Create montage cmd {}: '.format( cmd_montage )
|
|
cmd_montage_l = shlex.split(cmd_montage)
|
|
subprocess.call(cmd_montage_l)
|
|
|
|
# # resize output
|
|
tmp_output_files =[ (temp_dir+'/'+f) for f in (os.listdir(temp_dir)) if 'output' in f] #if more than 1 files results from montage
|
|
tmp_output_files = " ".join(tmp_output_files) # make into string
|
|
output_f = os.path.abspath('./'+args.output)
|
|
template_convert = "convert {input_f} -resize {w}x{h} -units PixelsPerInch -density 300x300 {output}"
|
|
cmd_convert = template_convert.format(
|
|
input_f= tmp_output_files,
|
|
w=size_sheet[0],
|
|
h=size_sheet[1],
|
|
output=output_f)
|
|
cmd_convert_l = shlex.split(cmd_convert)
|
|
print 'Convert montage to {} cmd: {}'.format(args.output, cmd_convert)
|
|
subprocess.call(cmd_convert_l)
|
|
|
|
print '** imposition save in', output_f, '**'
|
|
|
|
# garbage collection
|
|
cmd_rm = shlex.split( ('rm -rf '+ temp_dir) )
|
|
subprocess.call(cmd_rm ) # rm temp dir
|