Skip to content

Instantly share code, notes, and snippets.

@pyropeter
Created February 20, 2010 21:32
Show Gist options
  • Save pyropeter/309925 to your computer and use it in GitHub Desktop.
Save pyropeter/309925 to your computer and use it in GitHub Desktop.
Organize raw photos in gallery
#!/bin/sh
thumbpath="thumbs/"
size="300" # ufraw needs width and heigth to equal
fileext="jpg"
convertopts="-strip"
ufrawopts="--create-id=no --out-type=jpeg --compression=95 --size=$size"
ufrawopts="$ufrawopts --rotate=camera --wb=camera --grayscale=none --noexif"
rm -f thumbdata.csv
for rawfile in $(find . -type f -name "*.NEF" -prune | sort); do
thumbfile="$thumbpath$rawfile.$fileext"
if [ ! -e "$thumbfile" ]; then
echo "converting $rawfile..."
nice -n10 ufraw-batch --output="$thumbfile" $ufrawopts "$rawfile"
if [ "$?" != "0" ]; then
echo "ERROR, BYE BYE"
exit 1
fi
fi
exiv2 $rawfile | awk '/^Image timestamp/ {foo=substr($0, match($0, " : ")+3); print foo ",'$thumbfile'"}' >> thumbdata.csv
done
echo "Generating gallery..."
nice -n10 python imagegallery.py -x $size -y $size yes
echo "done."
import os
import sys
import re
import time
from optparse import OptionParser
parser = OptionParser(usage="usage: %prog [options] yes")
parser.add_option("-i", "--imagelist", dest="imagelist",
help="An csv-file containing [creation-datetime,path-to-thumb]", metavar="FILE",
default="thumbdata.csv")
parser.add_option("-o", "--output", dest="output",
help="gallery output prefix. the index will be $prefix.html, the pages $prefix????.html",
metavar="PREFIX", default="gallery")
parser.add_option("-x", "--width", dest="width",
help="Thumb's width", metavar="CSS-WIDTH",
default="100px")
parser.add_option("-y", "--height", dest="height",
help="Thumb's height", metavar="CSS-HEIGHT",
default="100px")
parser.add_option("-l", "--limit", dest="limit", type="int",
help="Images-per-page limit", metavar="NUM",
default=20)
(options, args) = parser.parse_args()
if not "yes" in args:
print "you have to confirm the order with the positional argument 'yes'"
sys.exit(1)
# ----------------------------
def timestampToText(ts):
return time.strftime("%a %d.%m.%Y %H:%M", time.localtime(ts))
# read imagelist and interpret and sort and split
filelist = []
for line in open(options.imagelist):
line = line.split(",")
filelist.append((time.mktime(time.strptime(
line[0].strip(), "%Y:%m:%d %H:%M:%S")), line[1].strip()))
filelist.sort(key=lambda x: x[0])
# -------------------------------------------------------
#while len(filelist):
# pages.append([])
# for x in range(options.limit):
# pages[-1].append(filelist.pop(0))
import random
import copy
def mutate(cut):
cut = copy.copy(cut)
for i in range(4):
if random.choice([True,False]) or len(cut) < 1:
cut.append(random.randint(0,len(filelist)-1))
else:
cut.pop(random.randint(0,len(cut)-1))
return cut
def evaluate(cut):
low_factor = 0
target = options.limit
target_factor = 1
duration_factor = (60*60*20)
cut.sort()
res = []
last = 0
for cutpoint in cut + [len(filelist)-1]:
res.append(
#low_factor/max(1,cutpoint-last) +
target_factor*(max(0,(cutpoint-last)-target)) +
duration_factor/float(max(1,filelist[cutpoint][0] - filelist[cutpoint-1][0])))
last = cutpoint
return sum(res)/len(res)
def simulate():
cut = []
temp = 100.0
score = evaluate(cut)
for x in range(500):
print "loop %3s, temp %8.2f, score %7.2f"%(x, temp, score)
children = []
scores = []
better = 5
for y in range(2000):
child = mutate(cut)
childscore = evaluate(child)
if childscore < score:
better -= 1
children.append(child)
scores.append(childscore)
if better < 1:
break
if temp < 1:
break
temp /= 1.1 # should be >1 :-P
# with 1.2 and 30 tries, avg: 28.0 28.7 27.6
# foo: 40% 50% 48%
# with 1.1 and 30 tries, avg: 20.1 19.6 19.4
# foo: 48% 45% 50%
# with 1.05 and 30 tires, avg: 14.1
# foo: 40%
best = len(scores) and min(scores) or False
if best and score > best:
temp += (score - best)
cut = children[scores.index(best)]
score = best
return cut
def swissArmyKnifeOfStatistics(values):
mean = sum(values)/float(len(values))
minimum = min(values)
maximum = max(values)
ssdev = (sum((x-mean)**2 for x in values)/float(max(len(values)-1,1)))**(
1/2.0)
return mean,minimum,maximum,ssdev
cuts = [simulate() for x in range(5)]
scores = [evaluate(x) for x in cuts]
print "Simulated. avg %7.3f, min %7.3f, max %7.3f, ssdev %7.3f"%(
swissArmyKnifeOfStatistics(scores))
"""(
sum(scores)/len(scores),
min(scores),
max(scores),
(max(scores)-min(scores))/(sum(scores)/len(scores))*100)"""
cut = cuts[scores.index(min(scores))]
pages = [[]]
for index,file in enumerate(filelist):
if index in cut:
pages.append([])
pages[-1].append(file)
#raise Exception
# -------------------------------------------------------
pagefile = open("%s.html"%(options.output), "w")
print >> pagefile, """<html><head><title>Image Gallery Index</title>
<style>
body {font-family:monospace; }
img {
vertical-align:middle;
max-width:""" + options.width + """;
max-height:""" + options.height + """; }
div {margin-top:60px; }
</style>
</head><body>"""
print >> pagefile, "<p>Generated by PyroPeter's Gallery-Creation-Script</p>"
print >> pagefile, "<p>Generation time: %s</p>"%time.strftime("%a, %d %b %Y %H:%M:%S",time.localtime())
for pagenum,filelist in enumerate(pages):
print >> pagefile, " <div>"
print >> pagefile, " <a href='gallery%s.html'>%s --- %s"%(
pagenum+1,
timestampToText(filelist[0][0]),
timestampToText(filelist[-1][0]))
print >> pagefile, " <br />[%s] %s Files"%(
pagenum+1, len(filelist))
print >> pagefile, " <br /><img src='%s' />"%(
filelist[0][1])
if len(filelist) > 1:
print >> pagefile, " <img src='%s' />"%(
filelist[-1][1])
print >> pagefile, " </a>"
print >> pagefile, " </div>"
print >> pagefile, "</body></html>"
# ----------------------------------------
for pagenum,filelist in enumerate(pages):
pagenum += 1
pagefile = open("%s%s.html"%(options.output,pagenum), "w")
imgs = ""
for foo,image in filelist:
imgs += "<div><a href='" + image + "' ><img src='" + image + "' /></a></div>\n"
print >> pagefile, """<html><head>
<title>Image Gallery [""" + str(pagenum) + """]</title>
<style>
body {font-family:monospace; }
img {
vertical-align:middle;
border:2px solid black;
max-width:""" + options.width + """;
max-height:""" + options.height + """; }
div {
height:""" + options.height + """;
width:""" + options.width + """;
margin:5px 5px 5px 5px;
float:left;
text-align:center; }
</style>
</head><body>"""
print >> pagefile, "<p>Generated by PyroPeter's Gallery-Creation-Script</p>"
print >> pagefile, "<p>Generation time: %s</p>"%time.strftime("%a, %d %b %Y %H:%M:%S",time.localtime())
print >> pagefile, "<p>Image count: %s</p>"%len(filelist)
print >> pagefile, "<p>Page: %s/%s</p>"%(pagenum,len(pages))
print >> pagefile, "<p>From: %s</p>"%(timestampToText(filelist[0][0]))
print >> pagefile, "<p>To: %s</p>"%(timestampToText(filelist[-1][0]))
print >> pagefile, imgs
print >> pagefile, "</body></html>"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment