Title: Photo Tools
1Photo Tools Perl scripts for digital photography
Jon Allen
http//perl.jonallen.info - jj_at_jonallen.info
2Organisation
- Digital photography can create lots of files
- Camera filenames are usually meaningless
- Manual file renaming
- Very time consuming
- Doesn't scale well (100s of folders, most called
"cats") - Use management software
- Many products import files into their own library
format - Difficult to use other tools or to change systems
3Ideal solution
- Standard directory structure, based on date
4ImageExifTool
- Cameras store image metadata as "EXIF tags"
- Timestamp, focal length, shutter speed, aperture,
etc. - ImageExifTool provides an API and command-line
utility to access and modify this data - See http//search.cpan.org/dist/Image-ExifTool
use ImageExifTool my exif
ImageExifTool-gtnew() my tags
exif-gtImageInfo(filename) say "Shutter speed
was tags-gtShutterSpeed"
5Getting the timestamp
- We need the timestamp as a TimePiece object
- TimePiece is a core module from Perl 5.10.0
- See http//search.cpan.org/dist/Time-Piece
sub exif_timestamp my filename shift my
format 'YmdHMS' my exif
ImageExifTool-gtnew() my tags
exif-gtImageInfo(filename,
DateFormatgtformat) return
TimePiece-gtstrptime(tags-gtDateTimeOriginal,
format)
6Change time zone
- Who remembers to update the clock on their camera
when going abroad? - Using TimePiece objects this is an easy fix
- TimeSeconds exports various useful constants
use TimePiece use TimeSeconds my time
exif_timestamp(filename) my offset -8 8
hours behind UK time offset ONE_HOUR
7Creating the new filenames
- Use a template gives flexibility
- TimePiece uses POSIX format specification
- Oracle date formats are more "human-friendly"
- http//search.cpan.org/dist/Convert-NLS_DATE_FORMA
T
use ConvertNLS_DATE_FORMAT qw/oracle2posix/ my
template '?YYYY/MM/DD/YYYY-MM-DD_HH24-MI-SS'
?my target time-gtstrftime(oracle2posix(temp
late)) Target filename is in the format
2008/05/13/2008-05-13_17-23-00
8Finishing up
- What next
- Prepend destination directory to target filename
- Check full path already exists (and if not,
create it) - Does the file already exist? If so, add a
sequence number (some cameras can take multiple
images per second) - Copy the file!
copy_rename( source gt filename,
destination gt destination_dir, template gt
template, offset gt offset, )
9Finding the source files
use FileFind Perl core module my
find_options find_optionsno_chdir
1 find_optionswanted sub if
(/\.(jpgjpejpegtiftiff)/i)
copy_rename( source gt
FileFindname, destination gt
destination_dir, template gt
template, offset gt offset, )
find(\find_options, source_directory)
10More uses for EXIF tags
- Keywords can be embedded in images
- Spotlight (OS X), Beagle (Linux), and Windows
search engines can read EXIF keywords
my keywords 'Dubai', 'Sunset' my exif
ImageExifTool-gtnew() exif-gtSetNewValuesFrom
File(filename) exif-gtSetNewValue('Keywords',k
eywords) exif-gtSetNewValue('XPKeywords',join ',
',_at_keywords) exif-gtWriteInfo(filename)
11Searching by keyword
12copyphotos.pl
- http//perl.jonallen.info/projects/copyphotos
./copyphotos.pl --offset-1 --template
"YYYY/MM_Mon/DD_Day/HH24-MI-SS"
--keyword "Dubai" -keyword "Sunset"
source/ photos/ Copying
source/a.jpg to photos/2004/01_Jan/25_Sunday/17-29
-05.jpg ... OK Copying source/b.JPG to
photos/2006/11_Nov/18_Saturday/16-55-13.JPG ...
OK Copying source/c.JPG to photos/2006/11_Nov/18_S
aturday/16-58-06.JPG ... OK Copying source/d.JPG
to photos/2006/01_Jan/28_Saturday/12-03-47.JPG
... OK
13Future enhancements
- Automatic keyword generation
- Camera knows when a picture was taken
- A GPS tracker knows where you were
- Your calendar (or phone) knows what you were
doing - Correlate these together into a list of keywords
14Camera aspect ratios
- Cameras typically use one of two aspect ratios
- 32 (11.5)
- Based on 35mm film format
- Canon, Nikon, Pentax, Sony DSLRs
- 43 (11.33)
- Olympus, Panasonic, Leica DSLRs
- Most compact digital cameras
15Printing the aspect ratio problem
- There are many "standard" paper sizes in use
- 6x4 (11.5)
- 7x5 (11.4)
- 10x8 (11.25)
- A4 (11.41)
- If the paper aspect ratio does not match your
camera, then part of the image will be cropped - Note that "full-bleed" printing will slightly
crop all sides of an image, even if the aspect
ratios match
16Headless chickens
- A standard 7x5 print does not match either of the
camera formats particularly well
32 format 7 lost (½")
43 format 5 lost (¼")
7x5
17Removing the need to crop
- Cropping can be avoided by adding a border
- Makes the image aspect ratio equal to the paper
7x5 paper 43 image No cropping!
18Find the original sizes
- How big is the image?
- How big is the paper?
use ImageSize my (width,height)
imgsize(filename)
use PaperSpecs my paper_size
'A4' PaperSpecs-gtunits('in') my page
PaperSpecs-gtfind(codegtpaper_size)
or die("Invalid paper size\n") my width
page-gtsheet_width my height
page-gtsheet_height
19Compare the aspect ratios
- Compare based on the longest sides
- With a 43 image and 7x5 paper
- paper_aspect 1.4, image_aspect 1.33
use ListUtil qw/max min/ my paper_longside
max(paper_width,paper_height) my
paper_shortside min(paper_width,paper_height)
my paper_aspect paper_longside /
paper_shortside my image_longside
max(image_width,image_height) my
image_shortside min(image_width,image_height)
my image_aspect image_longside /
image_shortside
20Which way to adjust?
- If paper_aspect gt image_aspect, we need to add
borders to the long side of the image - If image_aspect gt paper_aspect, we need to add
borders to the short side of the image
21Work out the new sizes
- Equal border on each side to centre the image
my target_longside image_longside my
target_shortside image_shortside my
(border_longside,border_shortside) (0,0) if
(paper_aspect gt image_aspect)
target_longside image_shortside
paper_aspect border_longside
(target_longside
image_longside) / 2 else
target_shortside image_longside /
paper_aspect border_shortside
(target_shortside -
image_shortside) / 2
22ImageMagick
- Open source image manipulation library
- Supports over 100 image formats
- Very high quality resizing algorithms
- Command-line tools and APIs for Perl, C, PHP,
.NET, etc - See http//www.imagemagick.org
23ImageMagick
- Open source image manipulation library
- Supports over 100 image formats
- Very high quality resizing algorithms
- Command-line tools and APIs for Perl, C, PHP,
.NET, etc - See http//www.imagemagick.org
- However
- Can be difficult to build
- Even harder to package!
- Remember Elaine's Law
- "Just make it easy to install, stupid!"
24ImageMagick
- Open source image manipulation library
- Supports over 100 image formats
- Very high quality resizing algorithms
- Command-line tools and APIs for Perl, C, PHP,
.NET, etc - See http//www.imagemagick.org
- However
- Can be difficult to build
- Even harder to package!
- Remember Elaine's Law
- "Just make it easy to install, stupid!"
FAIL
25Imager
- Self-contained Perl module
- http//search.cpan.org/dist/Imager
- Installs from CPAN shell
- Requires file format libraries (libjpeg, libtiff
etc) - Works with PAR!
- Include libraries with pp ?-l ./libjpeg.62.dylib
- Disadvantages
- Fewer facilities than ImageMagick
- Strips image metadata (EXIF)
26Adding a border with Imager
use Imager my source Imager-gtnew-gtread(filegt
source_filename) my dest Imager-gtnew(
xsize gt source-gtgetwidth() 2
border_width, ysize gt source-gtgetheight()
2 border_height, bits gt
source-gtbits, channels gt source-gtgetchannels
) dest-gtbox(filledgt1, colorgt'white') dest-gt
paste(imggtsource,
topgtborder_height, leftgtborder_width) dest-
gtwrite(filegttarget_filename,jpegqualitygt100)
27What happened to the colours?
- Unfortunately, Imager strips metadata
- This includes EXIF tags and the ICC colour
profile - ImageExifTool can copy the EXIF tags and ICC
profile back from the original file
use ImageExifTool ?my exif
ImageExifTool-gtnew() ?exif-gtSetNewValuesFromF
ile(source_filename) ?exif-gt?WriteInfo(target_
filename)
28Image aspect ratio changed
- We now have an image with the correct aspect
ratio, padded with borders on two sides - For a full-bleed print, we need a border around
all four sides of the image
29The problem with borders
- Applying an even border to a rectangular image
will affect its aspect ratio - A 7x5 image (1.4 aspect) with an even ½" border
would become an 8x6 image (1.33 aspect) - To keep the correct aspect ratio, we need to add
a ½" border to the short side and a (½ 1.4)"
border to the long side - How do we work this out in pixels?
30Calculating the border sizes
- 7x5 paper with ½" border
- Short side of image will be (5"-½"-½") 4"
- Image resolution 500px / 4" 125dpi
- Short side border ½" 125dpi 62.5px
- Long side border 62.5 1.4 87.5px
500px
700px
625px
875px
31photofit.pl
- http//perl.jonallen.info/projects/photofit
./photofit.pl --paper-size7x5 --border0.5in
sunset.jpg
32Fin!
Thank you for listening!
Any questions? http//perl.jonallen.info/talks