Automatic import of images: Multiple image directories

Starting with the script found on the page Automatic import of images: Versions not requiring Tkinter, I have created a new script that will take a collection of image directories and create 12-images-per-page documents from each of them in turn, save the documents and generate PDF files from each.

The initial input and output directories are specified in the code and will need to be changed based on your own configuration. They are defined on lines 21 and 22. There are many other settings that may be adjusted but this should work well enough as a starting point. Note that the script will not create the output directory so you'll need to make sure it exists before you start.

The basic idea here is to go through the source directory and gather all the sub-directory names. Then, go through each of those sub-directories and generate a document with the images found there, 12 per page. The document places the sub-directory name at the top of each page, arranges the images in four rows of three images with the file names centered under each. Page numbers are added. Since I print these documents double sided, the page numbers move from side to side and the entire page contents are shifted a little to the right (odd numbered pages) or the left (even numbered pages). Each gallery gets its own file.

Once generated, an SLA file is saved in the outputDirectory specified on line 22. Then, a PDF is generated with all pages and saved to the same location. Both files are named the same as the image sub-directory but with .sla and .pdf extensions respectively.

Caution: if you have directories with too many or very large image files, this can take a long while to run. Documents for directories with a dozen or two images of the appropriate size are created, saved, and exported to PDF in a matter of seconds. Documents for directories with images much larger than necessary or with more than a couple hundred images can take many minutes to be created. Since the images are printed at just over 1.4 by 2.1 inches, even at 300 dpi they will only need to be 420 by 633 pixels and you can probably get away with less. I would be cautious running this script on directories with lots of images or those copied directly from your digital camera. I've successfully produced documents with 640 images this way but it took a good while.

When I run this on a large number of directories, I often, eventually, get a Scribus Crash with the message: Scribus crashes due to the following exception : EXCEPTION_ACCESS_VIOLATION. I just close Scribus, move the image directories that have already been processed and start again. If anyone knows what's causing that and can fix it, that would be wonderful.

Considerable credit and thanks to Gregory Pittman, who wrote the original script on which this is based.


 * 1) !/usr/bin/env python

""" This is contact-sheet.py. This script will load the images from any number of directories, creating a new document of US Letter size from each directory.

AUTHOR: Henry Hartley, December 2, 2010, with thanks to Gregory Pittman

LICENSE: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

http://wiki.scribus.net/index.php/Automatic_import_of_images:_Multiple_image_directories

"""

import scribus import os

sourceDirectory = "C:/temp/photographs/images/" outputDirectory = "C:/temp/photographs/contact_sheets/"

filetype = [] dicttype = {'j':'.jpg','p':'.png','t':'.tif','g':'.gif','P':'.pdf'} Dicttype = {'j':'.JPG','p':'.PNG','t':'.TIF','g':'.GIF','P':'.PDF'}

firstPageNumber = '1' imagetype = 'jptgP' labelFont = 'Garamond Regular'

for t in imagetype[0:]: filetype.append(dicttype[t]) filetype.append(Dicttype[t])


 * 1) All of these numbers can be adjusted but what is here seems to work pretty well

marginX  = 36 marginY  = 36

iHorW  = 152 iVerW  = 101 iVerH = iHorW iHorH = iVerW
 * 1) Image height and width

gapW     = 24 gapH     = 21 xOffset  = 36 yOffset  = 24
 * 1) Gap sizes and page offsets

titleFS  = 12 titleX   = marginX titleY   = marginY titleW   = iHorW + iHorW + gapW + iHorW + gapW titleH   = titleFS * 2
 * 1) Page title text frame

labelGap = 0 labelFS  = 7 labelH   = labelFS * 3
 * 1) Image label text frame
 * 2) Height is enough to allow a second line of text if desired.

pNumFS   = 8 pNumY    = 759 pNumXt   = 2 pNumW    = 18 pNumH    = pNumFS * 1.5
 * 1) Page number text frame

H2V = int((iHorW-iHorH)/2) V2H = int((iVerH-iVerW)/2)

xPosH = [marginX, marginX + iHorW + gapW, marginX + (2 * iHorW) + (2 * gapW), marginX, marginX + iHorW + gapW, marginX + (2 * iHorW) + (2 * gapW), marginX, marginX + iHorW + gapW, marginX + (2 * iHorW) + (2 * gapW), marginX, marginX + iHorW + gapW, marginX + (2 * iHorW) + (2 * gapW)] yPosH = [marginY + yOffset + V2H, marginY + yOffset + V2H, marginY + yOffset + V2H, marginY + yOffset + iVerH + gapH + V2H, marginY + yOffset + iVerH + gapH + V2H, marginY + yOffset + iVerH + gapH + V2H, marginY + yOffset + (2 * iVerH) + (2 * gapH) + V2H, marginY + yOffset + (2 * iVerH) + (2 * gapH) + V2H, marginY + yOffset + (2 * iVerH) + (2 * gapH) + V2H, marginY + yOffset + (3 * iVerH) + (3 * gapH) + V2H, marginY + yOffset + (3 * iVerH) + (3 * gapH) + V2H, marginY + yOffset + (3 * iVerH) + (3 * gapH) + V2H] xPosV = [marginX + H2V, marginX + iHorW + gapW + H2V, marginX + (2 * iHorW) + (2 * gapW) + H2V, marginX + H2V, marginX + iHorW + gapW + H2V, marginX + (2 * iHorW) + (2 * gapW) + H2V, marginX + H2V, marginX + iHorW + gapW + H2V, marginX + (2 * iHorW) + (2 * gapW) + H2V, marginX + H2V, marginX + iHorW + gapW + H2V, marginX + (2 * iHorW) + (2 * gapW) + H2V] yPosV = [marginY + yOffset, marginY + yOffset, marginY + yOffset, marginY + yOffset + iVerH + gapH, marginY + yOffset + iVerH + gapH, marginY + yOffset + iVerH + gapH, marginY + yOffset + (2 * iVerH) + (2 * gapH), marginY + yOffset + (2 * iVerH) + (2 * gapH), marginY + yOffset + (2 * iVerH) + (2 * gapH), marginY + yOffset + (3 * iVerH) + (3 * gapH), marginY + yOffset + (3 * iVerH) + (3 * gapH), marginY + yOffset + (3 * iVerH) + (3 * gapH)] imgID = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] imgRow = 3 imagedir = ""
 * 1) It's quite likely that these longs lists could be replaced by a formula.
 * 2) If anyone has the time to do that, it would probably make this script easier
 * 3) to maintain.

dirCount = 0 dir = os.listdir(sourceDirectory) DIR = [] for file in dir: #result = scribus.messageBox("Directory", "File: "+file) if os.path.isdir(sourceDirectory+file): DIR.append(file) dirCount += 1 DIR.sort


 * 1) result = scribus.messageBox("Directory Count", "There were "+str(dirCount)+" directories added to the array")

for imagedir in DIR: #result = scribus.messageBox("Directory", "The directory about to be processed is: "+imagedir) d = os.listdir(sourceDirectory+imagedir) D = [] for file in d:		for format in filetype: if file.endswith(format): D.append(file) D.sort gallerytitle = imagedir imageCount = 0 pageNumber = 1 scribus.progressTotal(len(D)) if len(D) > 0: if scribus.newDoc(scribus.PAPER_LETTER, (marginX, marginX, marginY, marginY),scribus.PORTRAIT, 1, scribus.UNIT_POINTS, scribus.NOFACINGPAGES, scribus.FIRSTPAGERIGHT): while imageCount < len(D): if imageCount > 0: scribus.newPage(-1) # Here is where we're loading images into the page, four, six, or twelve at a time, then go back up for a newPage if pageNumber % 2 == 0: pOffset = 0 pNumX = xPosH[0] else: pOffset = xOffset pNumX = xPosH[pNumXt] + iHorW + pOffset - pNumW # L is the frame at the top of each page showing the gallery title (read in above) L = scribus.createText(titleX + pOffset, titleY, titleW, titleH) scribus.setText(gallerytitle, L)				scribus.setTextAlignment(scribus.ALIGN_CENTERED, L)				scribus.setFont(labelFont, L)				scribus.setFontSize(titleFS, L)				for i in imgID: if imageCount < len(D): scribus.statusMessage("Placing image " + D[imageCount] + " in document (" + `imageCount` + " of " + `len(D)` + ")") scribus.progressSet(imageCount) # Create a temporary image object. Size and location are irrelivant tempImage = scribus.createImage(10, 10, 10, 10) # Populate that object with your image scribus.loadImage(sourceDirectory+imagedir + '/' + D[imageCount], tempImage) # Scale the image but NOT proportionally scribus.setScaleImageToFrame(scaletoframe=1, proportional=0, name=tempImage) # Use getImageScale to get the relative scaling in the x and y directions imgx,imgy = scribus.getImageScale(tempImage) # If imgx < imgy, you have an horizontal image, otherwise, # a vertical (or square) image. if imgx < imgy: x = xPosH[i] + pOffset y = yPosH[i] pWidth = iHorW pHeight = iHorH else: x = xPosV[i] + pOffset y = yPosV[i] pWidth = iVerW pHeight = iVerH # Can't have these cluttering up the page scribus.deleteObject(tempImage) # Now we create the REAL image object placed appropriately f = scribus.createImage(x, y, pWidth, pHeight) # and load the image scribus.loadImage(sourceDirectory+imagedir + '/' + D[imageCount], f)						# this time when we scale the image, we do it proportionally scribus.setScaleImageToFrame(scaletoframe=1, proportional=1, name=f) # Lpic is the label for each picture, the position is the same for all #	image orientations and the labels are centered under the pictures. # Create the text frame. Lpic = scribus.createText(xPosH[i] + pOffset, yPosV[i] + iVerH + labelGap, iHorW, labelH) # populate with the file name scribus.setText(D[imageCount], Lpic) # and format as desired scribus.setTextAlignment(scribus.ALIGN_CENTERED, Lpic) scribus.setFont(labelFont, Lpic) scribus.setFontSize(labelFS, Lpic) #scribus.setFillColor("White", Lpic) # increment the image count imageCount += 1 # Now the page number # Create a text frame pNum = scribus.createText(pNumX, pNumY, pNumW, pNumH) # Put the page number in it and format pageNumberPrint = pageNumber + (int(firstPageNumber)-1) scribus.setText(`pageNumberPrint`, pNum) if imageCount < len(D): scribus.setTextAlignment(scribus.ALIGN_RIGHT, pNum) else: scribus.setTextAlignment(scribus.ALIGN_LEFT, pNum) scribus.setFont(labelFont, pNum) scribus.setFontSize(pNumFS, pNum) #scribus.setFillColor("White", pNum) # Finally, we increment the page number pageNumber += 1 scribus.setRedraw(1) scribus.redrawAll else: result = scribus.messageBox ('Not Found','No Images found with\n this search selection',scribus.BUTTON_OK) scribus.setRedraw(1) scribus.redrawAll scribus.statusMessage("Saving File as "+outputDirectory+imagedir) #result = scribus.messageBox("Save", "Saving SLA File as: "+outputDirectory+imagedir+".sla") scribus.saveDocAs(outputDirectory+imagedir+".sla") scribus.statusMessage("Saving PDF File as "+outputDirectory+imagedir) pdfExport = scribus.PDFfile pdfExport.info = outputDirectory+imagedir+".pdf" pNum = 1 PDFPages = [] while pNum < pageNumber: PDFPages.append(pNum) pNum += 1 pdfExport.pages = PDFPages pdfExport.file = outputDirectory+imagedir+".pdf" pdfExport.save scribus.closeDoc scribus.statusMessage("") scribus.progressReset