Making a photobook from a directory of images using a script: Difference between revisions
No edit summary |
No edit summary |
||
Line 4: | Line 4: | ||
It's intended to produce a book in the same format as Adobe Photoshop Album: US Letter, landscape orientation. | It's intended to produce a book in the same format as Adobe Photoshop Album: US Letter, landscape orientation. | ||
Caveat: I learned Python for the sole purpose of writing this script. It's a little rough in places. | |||
== Usage == | == Usage == | ||
Line 258: | Line 260: | ||
pb_create_album() | pb_create_album() | ||
</nowiki</pre> | </nowiki></pre> | ||
== pb_flip_h.py == | |||
<pre><nowiki> | |||
#!/usr/bin/env python | |||
# -*- coding: ascii -*- | |||
# File: pb_flip_h.py | |||
# Created: 25th May 2007 by Chris Crouch | |||
# flip the images on the current page horizontally | |||
import photobook_layout | |||
try: | |||
from scribus import * | |||
except ImportError: | |||
print "This script only runs from within Scribus." | |||
sys.exit(1) | |||
###### | |||
def pb_flip_h(): | |||
# flip the images on the current page horizontally | |||
deselectAll() | |||
page_margins = photobook_layout.get_page_margins() | |||
page_width = photobook_layout.page_size[0] - page_margins[0] - page_margins[2] | |||
page_height = photobook_layout.page_size[1] - page_margins[1] - page_margins[3] | |||
objs = photobook_layout.get_images_on_page() | |||
for obj in objs: | |||
obj_size = getSize(obj) | |||
obj_pos = getPosition(obj) | |||
obj_h_mid = obj_pos[0] + obj_size[0]/2 | |||
new_h_mid = page_width - (obj_h_mid - page_margins[0]) + page_margins[0] | |||
selectObject(obj) | |||
moveObjectAbs(new_h_mid - obj_size[0]/2, obj_pos[1], obj) | |||
deselectAll() | |||
docChanged(True) | |||
###### | |||
if __name__ == '__main__': | |||
pb_flip_h() | |||
</nowiki></pre> | |||
== pb_flip_v.py == | |||
<pre><nowiki> | |||
#!/usr/bin/env python | |||
# -*- coding: ascii -*- | |||
# File: pb_flip_v.py | |||
# Created: 25th May 2007 by Chris Crouch | |||
import photobook_layout | |||
try: | |||
from scribus import * | |||
except ImportError: | |||
print "This script only runs from within Scribus." | |||
sys.exit(1) | |||
###### | |||
def pb_flip_v(): | |||
# flip the images on the current vertically | |||
deselectAll() | |||
page_margins = get_page_margins() | |||
page_width = page_size[0] - page_margins[0] - page_margins[2] | |||
page_height = page_size[1] - page_margins[1] - page_margins[3] | |||
objs = get_images_on_page() | |||
for obj in objs: | |||
obj_size = getSize(obj) | |||
obj_pos = getPosition(obj) | |||
obj_v_mid = obj_pos[1] + obj_size[1]/2 | |||
new_v_mid = page_height - (obj_v_mid - page_margins[1]) + page_margins[1] | |||
selectObject(obj) | |||
moveObjectAbs(obj_pos[0], new_v_mid - obj_size[1]/2, obj) | |||
deselectAll() | |||
docChanged(True) | |||
###### | |||
if __name__ == '__main__': | |||
photobook_layout.pb_flip_v() | |||
</nowiki></pre> | |||
== pb_layout_current.py == | |||
<pre><nowiki> | |||
#!/usr/bin/env python | |||
# -*- coding: ascii -*- | |||
# File: pb_layout_current.py | |||
# Created: 25th May 2007 by Chris Crouch | |||
import photobook_layout | |||
###### | |||
if __name__ == '__main__': | |||
photobook_layout.pb_layout_page() | |||
</nowiki></pre> | |||
== pb_layout_from_current.py == | |||
<pre><nowiki> | |||
#!/usr/bin/env python | |||
# -*- coding: ascii -*- | |||
# File: pb_layout_from_current.py | |||
# Created: 25th May 2007 by Chris Crouch | |||
import photobook_layout | |||
###### | |||
if __name__ == '__main__': | |||
photobook_layout.pb_layout_all_pages() | |||
</nowiki></pre> |
Revision as of 03:50, 26 May 2007
This is yet another script to layout photos in a book. It differs from Automatic import of images: Versions not requiring Tkinter and Automatic import of images from a directory using a script in that it is not meant to be fuly automatic, and it allows for a variable number of images per page in mixtures of landscape and portrait orientation.
It's intended to produce a book in the same format as Adobe Photoshop Album: US Letter, landscape orientation.
Caveat: I learned Python for the sole purpose of writing this script. It's a little rough in places.
Usage
Running photobook_layout.py without an open document will bring up a dialog to select a directory. The script will then add all JPEG files (*.jpg) to a new document, 3 to a page. It will then go through each page, re-orienting and resizing the photos to nicely fit the page.
You can then re-arrange the photos, dragging them from page to page to get a nice layout. Re-running the photobook_layout.py script will go through all of the pages, re-laying them out.
The script can handle 1-4 photos per page, in any combination of portrait and landscape.
There are some auxilliary scripts. pb_layout_current.py will lay out only the current page. pb_layout_from_current.py will lay out all pages from the current one to the end of the document. pb_flip_h.py and pb_flip_v.py will flip arrangement of images on the current page.
photobook_layout.py
#!/usr/bin/env python # -*- coding: ascii -*- # File: photobook_layout.py # Created: 25th May 2007 by Chris Crouch # This script will create a photobook. It can both create a photobook from a folder full of images, # and lay images out on the pages in a nice way. You can move the images from page to page, and have # the script re-layout them for you. It lays out landscape and portrait images neatly. # Requires the Python Image Library from http://www.pythonware.com/products/pil/ (to work out image orientation) # Developed on a Windows machine running Scribus 1.3.3.9 # This is designed for Letter pages in Landscape orientation, with images that are 3:2 aspect ratio (DSLR) # To change these, change the constants at the top for the paper size, then you'll need to just fiddle # with the size & positions in pb_layout_page() so that (a) the image frames are the correct aspect ratio, # and (b) the sizes and positions look good on the page. Trial and error is how I got these. # There are some auxilliary scripts that just allow you to directly invoke some of the functions in this script. import glob try: import Image except ImportError: print "This script requires the Python Image Library" sys.exit(1) try: from scribus import * except ImportError: print "This script only runs from within Scribus." sys.exit(1) ###### Constants page_size = (279.4, 215.9) #Letter, mm page_margins_left = (5, 5, 20, 5) #mm page_margins_right = (20, 5, 5, 5) #mm page_margins_points = (56.69, 14.17, 14.17, 14.17) #margins_right as points ###### def cmpObj(obj1, obj2): # compare 2 image objects to sort by horizontal loc # (if ==, the vert. pos; then by name pos1 = getPosition(obj1) pos2 = getPosition(obj2) if pos1[0] > pos2[0]: return 1 if pos1[0] < pos2[0]: return -1 if pos1[1] > pos2[1]: return 1 if pos1[1] < pos2[1]: return -1 return obj1 > obj2 ###### def get_page_margins(): if (currentPage() % 2) == 1: return page_margins_right; else: return page_margins_left; ###### def placeobj(obj_size, x_place, y_place, obj): # move obj to specified position and specified size # obj_size - (w, h) # x_place, y_place: 0.0 - 1.0 normalized page_margins = get_page_margins() page_width = page_size[0] - page_margins[0] - page_margins[2] page_height = page_size[1] - page_margins[1] - page_margins[3] xpos = (page_width * x_place) + page_margins[0] - obj_size[0]/2 ypos = (page_height * y_place) + page_margins[1] - obj_size[1]/2 selectObject(obj) sizeObject(obj_size[0], obj_size[1], obj) moveObjectAbs(xpos, ypos, obj) deselectAll() return ###### def get_images_on_page(): # returns a list of the image objects on the current page # get all the items on the page item_list = getPageItems() # refine it to a list of only image objects objs = []; for item in item_list: if item[1] == 2: #type 2 == image objs.append(item[0]) return objs ###### def pb_layout_page(): # Nicely layout all of the images on the current page deselectAll() # get all of the images on this page and sort them by position objs = get_images_on_page() if len(objs) == 0: return objs.sort(cmpObj) # refine it to lists of landscape & portrait images port = [] land = [] for obj in objs: file = getImageFile(obj) im = Image.open(file) sz = im.size if sz[0] > sz[1]: land.append(obj) else: port.append(obj) np = len(port) # number of portrait images nl = len(land) # number of landscape images # layouts for different numbers of portrait and landscape images if np==0 and nl==1: placeobj((240, 160), 0.5, 0.5, land[0]) elif np==0 and nl==2: placeobj((150, 100), 0.4, 0.25, land[0]) placeobj((150, 100), 0.6, 0.75, land[1]) elif np==0 and nl==3: placeobj((120, 80), 0.25, 0.21, land[0]) placeobj((165, 110), 0.5, 0.7, land[1]) placeobj((120, 80), 0.75, 0.21, land[2]) elif np==0 and nl==4: placeobj((120, 80), 0.25, 0.25, land[0]) placeobj((120, 80), 0.75, 0.25, land[1]) placeobj((120, 80), 0.25, 0.75, land[2]) placeobj((120, 80), 0.75, 0.75, land[3]) elif np==1 and nl==0: placeobj((144, 216), 0.74, 0.5, port[0]) elif np==1 and nl==1: placeobj((90, 135), 0.205, 0.5, port[0]) placeobj((150, 100), 0.7, 0.5, land[0]) elif np==1 and nl==2: placeobj((120, 180), 0.25, 0.5, port[0]) placeobj((120, 80), 0.75, 0.27, land[0]) placeobj((120, 80), 0.75, 0.73, land[1]) elif np==1 and nl==3: placeobj((130, 195), 0.27, 0.5, port[0]) placeobj((90, 60), 0.75, 0.18, land[0]) placeobj((90, 60), 0.75, 0.5, land[1]) placeobj((90, 60), 0.75, 0.82, land[2]) elif np==2 and nl==0: placeobj((120, 180), 0.25, 0.5, port[0]) placeobj((120, 180), 0.75, 0.5, port[1]) elif np==2 and nl==1: placeobj((60, 90), 0.14, 0.25, port[0]) placeobj((60, 90), 0.14, 0.75, port[1]) placeobj((180, 120), 0.63, 0.5, land[0]) elif np==2 and nl==2: placeobj((70, 105), 0.22, 0.27, port[0]) placeobj((70, 105), 0.78, 0.73, port[1]) placeobj((135, 90), 0.65, 0.24, land[0]) placeobj((135, 90), 0.35, 0.76, land[1]) elif np==3 and nl==0: placeobj((80, 120), 0.17, 0.5, port[0]) placeobj((80, 120), 0.5, 0.5, port[1]) placeobj((80, 120), 0.83, 0.5, port[2]) elif np==3 and nl==1: placeobj((120, 180), 0.25, 0.5, port[0]) placeobj((60, 90), 0.62, 0.72, port[1]) placeobj((60, 90), 0.87, 0.72, port[2]) placeobj((120, 80), 0.745, 0.26, land[0]) elif np==4 and nl==0: placeobj((90, 135), 0.19, 0.5, port[0]) placeobj((60, 90), 0.5, 0.25, port[1]) placeobj((60, 90), 0.5, 0.75, port[2]) placeobj((90, 135), 0.81, 0.5, port[3]) docChanged(True) deselectAll() return ###### def pb_layout_all_pages(): # re-layout all pages from the current page to the end of the document progressReset() progressTotal(pageCount()+1) messagebarText("Arranging pictures"); for i in range(currentPage(), pageCount()+1): gotoPage(i) progressSet(i) messagebarText("Page "+str(i)) pb_layout_page() progressReset() messagebarText(""); ###### def pb_create_album(): # Prompt the user for a directory to process. # Create a new document with all jpg files from the selected directory added as images # to the document, 3 to the page. # When finished, process the document to layout the images in a "nice" manner dirname = fileDialog("Select Directory","","",False,False,True) files = glob.glob(dirname + "*.jpg") if len(files) == 0: return # it seems that you _have_ to specify page margins in points newDocument(PAPER_LETTER, page_margins_points, LANDSCAPE, 1, UNIT_POINTS, PAGE_2, FACINGPAGES, FIRSTPAGERIGHT) zoomDocument(50) setUnit(UNIT_MILLIMETERS) setMargins(page_margins_right[0], page_margins_right[1], page_margins_right[2], page_margins_right[3]) progressReset() progressTotal(len(files)) messagebarText("Creating pages..."); progress = 0; num_on_page = 0; for file in files: messagebarText("Adding "+file) progressSet(progress) progress = progress + 1 num_on_page = num_on_page + 1 if num_on_page == 4: newPage(-1) num_on_page = 1 im = Image.open(file) sz = im.size if sz[0] > sz[1]: f = createImage(num_on_page*90-80, 60, 90, 60) else: f = createImage(num_on_page*90-80, 10, 80, 120) loadImage(file, f) setScaleImageToFrame(scaletoframe=1, proportional=1, name=f) progressReset() messagebarText(""); deselectAll() # now layout the pages nicely gotoPage(1) pb_layout_all_pages() deselectAll() ###### if __name__ == '__main__': # either create a new album document, or re-layout the entire existing document if haveDoc(): gotoPage(1) pb_layout_all_pages() else: pb_create_album()
pb_flip_h.py
#!/usr/bin/env python # -*- coding: ascii -*- # File: pb_flip_h.py # Created: 25th May 2007 by Chris Crouch # flip the images on the current page horizontally import photobook_layout try: from scribus import * except ImportError: print "This script only runs from within Scribus." sys.exit(1) ###### def pb_flip_h(): # flip the images on the current page horizontally deselectAll() page_margins = photobook_layout.get_page_margins() page_width = photobook_layout.page_size[0] - page_margins[0] - page_margins[2] page_height = photobook_layout.page_size[1] - page_margins[1] - page_margins[3] objs = photobook_layout.get_images_on_page() for obj in objs: obj_size = getSize(obj) obj_pos = getPosition(obj) obj_h_mid = obj_pos[0] + obj_size[0]/2 new_h_mid = page_width - (obj_h_mid - page_margins[0]) + page_margins[0] selectObject(obj) moveObjectAbs(new_h_mid - obj_size[0]/2, obj_pos[1], obj) deselectAll() docChanged(True) ###### if __name__ == '__main__': pb_flip_h()
pb_flip_v.py
#!/usr/bin/env python # -*- coding: ascii -*- # File: pb_flip_v.py # Created: 25th May 2007 by Chris Crouch import photobook_layout try: from scribus import * except ImportError: print "This script only runs from within Scribus." sys.exit(1) ###### def pb_flip_v(): # flip the images on the current vertically deselectAll() page_margins = get_page_margins() page_width = page_size[0] - page_margins[0] - page_margins[2] page_height = page_size[1] - page_margins[1] - page_margins[3] objs = get_images_on_page() for obj in objs: obj_size = getSize(obj) obj_pos = getPosition(obj) obj_v_mid = obj_pos[1] + obj_size[1]/2 new_v_mid = page_height - (obj_v_mid - page_margins[1]) + page_margins[1] selectObject(obj) moveObjectAbs(obj_pos[0], new_v_mid - obj_size[1]/2, obj) deselectAll() docChanged(True) ###### if __name__ == '__main__': photobook_layout.pb_flip_v()
pb_layout_current.py
#!/usr/bin/env python # -*- coding: ascii -*- # File: pb_layout_current.py # Created: 25th May 2007 by Chris Crouch import photobook_layout ###### if __name__ == '__main__': photobook_layout.pb_layout_page()
pb_layout_from_current.py
#!/usr/bin/env python # -*- coding: ascii -*- # File: pb_layout_from_current.py # Created: 25th May 2007 by Chris Crouch import photobook_layout ###### if __name__ == '__main__': photobook_layout.pb_layout_all_pages()