On the right side of my home page (link provided for LiveJournal readers) you may notice the new "My Photo Gallery" entry. This is the result of a decision made on Friday around 11 a.m. and realized at about 2:00 a.m. on Saturday morning: should I keep working with my craptacular old slideshow scripting program, or write something new?
In neither case was the program entirely new. Both programs are modifications of PHP SlideShow, a fine free slideshow viewer from the brain boys at Zinkwazi.com. My old script was pre-historic, and I had extensively modified it. It would display each image in a uniform size, clicking upon which would launch a separate full-sized browser window for viewing. It could display a link to movie files. And the first time you ran it, you could add comments which would then be saved for posterity, the idea being that the photo's author (presumably me) would do that promptly. In practice that was often not the case.
The new PHP Slideshow has many neat features, chief of which is that it uses an external template file for styling, allowing for an almost infinite variety of presentations. Unfortunately it lacked my movie-display and comment features.
So I had a choice: do I try to fix up my old craptacular software for The Big Trip, or do I undertake to re-add my features to the new, entirely rewritten version of PHP SlideShow?
I decided to dig into it, starting with comments. I discovered that the new software could show something called "EXIF" comments, which as it turns out are comments saved inside the image file. This was great, since once I added them the comments would STAY with the photo: if I sent someone a photo, the comment would be inside, ready to be retrieved. So to get that to work I needed a way to add EXIF comments to existing images, and since I plan on using this on the upcoming Big Trip, I needed both Windows and Linux methods.
For Windows I found a program called EXIFer that worked, although like most Windows programs it doesn't understand interface design. Just starting the program takes several mouse clicks, you can't drag image files to open them, and once you have hunted up a file, the comment editor is buried on a menu bar. However, a few tests confirmed that both it and the PHP SlideShow software worked together to put EXIF comments on the screen, so that's better than nothing!
For Linux I finally located EXIV2, which provided a nifty command-line utility for reading and writing comment fields, among other things.
Now this is a sweet solution, because once the comments are added to the image, they stay with the image. The same can be done with the thumbnails, and as soon as I figure out that bit I'm going to change the script to use EXIF thumbnails. But for now regular thumbnails will do.
I also stumbled into bash scripting, which I had never worked with before. I know, I know, this is like saying "Hey, I just got this thing called Cable Television - ever heard of it? It has many channels." But frankly I stay out of unwinnable battles like PC vs Mac or Coke vs Pepsi, and the mid-90's were all "Whose Shell Is Better", with sh-vs.-ksh-vs.-csh-vs.-bash and frankly I wanted no part of it. I knew sh and csh, and I decided ot wait for the rest of the Shell Wars to settle out. (Apologies to those of you who are not Unix geeks.)
But bash turned out to have tools to make do-looped scripts, something I've never gotten the hang of in other shell languages. I've done it, I've written loops, but afterwards I can never retain the knowledge of how I did it, like McCoy sewing Spock's Brain back into his head with the help of alien teaching machines.
Nevertheless a few minutes of prodding, and I had a quick-and-dirty method of adding comments to all the images in a directory:
for i in *.jpg do comment=`/usr/bin/exiv2 -p c $i` if [ -z "$comment" ] then echo Add comment for $i read comment /usr/bin/exiv2 -c "$comment" $i echo Added $i:$comment else echo $i comment is $comment fi done |
It looks for an existing comment, and if there isn't one asks for input and adds the comment.
I tried adding a feature to the script to put this functionality into PHPSlidesShow, but with no native routines for writing EXIF comments, I didn't want to start executing shell commands. That just opens up too many security holes for my taste, and besides I had other things to do.
I already had c-shell alias for making jpg thumbnails. With my new bash tricks, I quickly turned that into a thumbnail looping script. Up til now I made thumbnails by running my alias in a hand-generated csh for-loop.
#!/bin/bash mkdir thumbs for i in *.jpg do djpeg $i | pnmscale -xysize 48 38 | cjpeg -opti -progr -qual '75%' > thumbs/$i echo $i processed done |
Now, I wasn't satisfied with the lame "this is a movie" generic thumbnail I'd created for my old scripting system (see beginning of today's entry). And I knew that my linux desktop displayed a thumbnail sample frame from within .mov files. So knowing it was possible, I soon cobbled together my own version based on what I already knew (my djpeg based thumbnailer) and what I learned about ffmpeg turning out .mov thumbnail gifs.
#!/bin/bash
for i in *.mov
do
j=${i/mov/jpg}
g=${i/mov/gif}
ffmpeg -i $i -f gif -t 0.001 $g
convert $g $j
djpeg $j | pnmscale -xysize 48 38 | cjpeg -opti -progr -qual 75% > thumbs/$j
rm -f $g
echo $j processed
done
|
It's a little clumsy because for some reason the ffmpeg on my computer doesn't want to turn out jpg files. Gifs it does, so I convert them to jpeg to make an image file, and then cough up a thumbnail. However kludgy, the result worked, and I had video thumbnail files.
Now I needed to sew them all together inside the PHPSlideShow program. Like most freeware php, it is a largely-inscrutable mass of sparsely-commented spaghetti code - worse this time because a new automatically-generate-thumbnails-over-FTP kludge has been recently installed. A little studying, and I found that the entire program culminated in one line:
echo $template; |
That being the case, I figured I could try just shoehorning my own code in right before this step.
// Strip off the extension $image_movie=substr($image_filename,0,strpos($image_filename,".")); |
One problem I encountered right off was that the program was written to deal with only one pair of files at a time: an image file, and an identically-named thumbnail file in a subdirectory. But I was introducing the concept of a third file which would have an entirely different extension, ".mov" for now (later ".mpg" or ".wmv" seem likely). So I had to figure out the "substr" trick up there in order to change "filename.jpg" or "filename.tiff" to "filename".
Then the appropriate ".mov" can be tagged on the end easily enough.
// Look for .mov extension of same filename
if( file_exists( "$path_to_images/$image_movie.mov" ) ) {
// Build size-of-movie string, first see if it's "X-many K" in size
$movie_size=sprintf("%.2f", filesize("$path_to_images/$image_movie.mov")/1024);
$movie_unit="K";
// then see if it's "X-many M" in size
if ( $movie_size > 1024 ) {
$movie_size = sprintf("%.2f",$movie_size/1024);
$movie_unit="M";
}
|
I thought I was rather clever to simply repeatedly divide by 1024, rather than trying to be smart and measuring the size, and then comparing it against 1024 for K or 1024^2 for M. Just keep dividing it! Presently image files aren't commonly in the Gigabyte range, so that didn't seem necessary: I'm sure readers from the distant future of 2010 are laughing at our tiny, grainy, low-resolution movies and mere-megabit-per-second bandwidth. Scoff if you will, but at least WE don't have to put up with the escaped clones of Bill Gates panhandling on every streetcorner. Yet.
// Link to open new window to show movie (would like to size to fit)
$template = str_replace(" |
Adding the movie size is a dead necessity, IMO. Nothing I hate worse than committing to download some arbitrarily large movie file.
Anyway, that's it: the script basically says "If a .jpg file has a corresponding .mov file, link to the .mov file and show its size."
Here's a link to the revised file, my code begins at line 340.
The script works by successively replacing tags in a template file, so I had to create a new <IMAGE_MOVIE> tag in the template file as well.
Anyway, after all that coding and having it actually work, i was ecstatic. I began life as a coder thirty years ago this September, and it's nice to see I can still kludge a script given enough time. But it was time to head home at that point, so I ran out to catch the bus, and as I got on board I noticed masking tape over the paybox - the day was so good, even my bus ride was free!
When I got home I was so energized by my little accomplishment that I undertook another project that had long been delayed: building a photo gallery of my best pictures. Sorting through ALL my online pictures, even very quickly, took me till 2:00 a.m., and bedtime was further delayed when a glitch in my thumbnail script (since resolved) kept duplicating the entire contents of my gallery image directory under sequentially-numbered identical names.
However my son was having his pre-Big Trip 15th birthday party with his friends, so it's not like I would have been sleeping anyway.
As I climbed happily into bed, the warm glow of my swanky new image gallery coursing through my brain, I remembered that I had a 7:00 a.m. appointment with Red Cross Apheresis...
I made it... but that's another story...
Posted by Albatross at July 15, 2006 3:24 PM | TrackBack