fogbound.net




Sun, 25 Sep 2011

Photoshop scripting with Javascript

— SjG @ 6:41 pm

I’ve played with the Javascript interface to Photoshop for a couple of years. Conceptually, it’s great — a simple, powerful, interpreted language like Javascript, with an API to interface to one of the best image-processing packages available. In practice, it’s not as good as it is in concept, but it’s still pretty good. The API doesn’t include all of Photoshop’s functionality directly, and there are a lot of things you need to execute as fairly obscure event actions. These event actions aren’t documented, but can be determined by activating a plug-in which logs everything that you do using the Photoshop GUI — you can then read through these logs, and copy the actions you need.

Still, there are some real advantages to using this Javascript interface, as opposed to something designed for the purpose like, say, Processing. You can use the Photoshop UI for controlling inputs to your script (set foreground colors, select portions of the image, select specific layers, etc.), and output your manipulations directly into Photoshop layers.

I’ll be posting here shortly a library I’ve created for easily building dialog panels for setting script options. I find that most manipulations I want to do have a set of variables, and I’d rather not tweak the code each time I want to change them.

This library was originally written under Photoshop 10 (aka CS3). Under version 11 (aka CS4), it was less stable. Sometimes it would crash out at odd places complaining that I was referencing properties of undefined objects. Because there have been memory leaks and other issues with the Javascript interpreter, these seemingly random failures were annoying but not too surprising. When it came to version 12 (aka CS5), I was rarely able to run my scripts at all. What made it frustrating was the apparent randomness of the crashes. I could print a variable to the console, and the very next line would crash out with an “undefined object” error when referencing that variable.
To make a long story short, I was able to track down the issue. It turns out that in iterations, declaring variables matters. That is to say:
for (i in someCollection)
{
$.writeln(i['someAttribute']);
}

will cause random crashes, but
for (var i in someCollection)
{
$.writeln(i['someAttribute']);
}

runs beautifully. Now, I “knew” that the var keyword is optional and used for specifying scope, but I never had any idea that there could be an issue within the scope of a simple loop. Obviously, Javascript didn’t know that I intended i to be a variable on each iteration — perhaps it thinks I meant for i to be a 1957 Chevy Belair on some iterations.

In any case, having cracked the code as it were, I have proceeded to enhance and add to my library. After a little more testing, I’ll be posting it here or on GitHub.


Fri, 19 Aug 2011

Timelapse Photography and the Evolution of Hardware

— SjG @ 10:29 pm

We’ve had some new hatches in the Butterfly Fort, and there are at least six chrysalids which will be eclosing in the next couple of days1. This reawakens my interest in time-lapse photography.

I used to have a setup with a Harbortronics D2000 which I hooked up to my Nikon Coolpix 950 (and, later, Coolpix 995). It was good for a lot of things, but I succeeded in burning a nice streak across the sensor of the camera when the sun passed directly through the scene — the Coolpix line didn’t have a physical shutter, so the lens focused the sun onto the delicate sensor for the full time it was in view.

I’ve been using the Brinno Gardenwatch Cam that I received as a gift
a few years ago. It’s a dedicated, all-in-one time-lapse device. Once I learned a few things, I was able to use it successfully. First off, it really needs to be run on Nickel-metal hydride batteries. Next, you have to listen carefully when turning it on, because it’s not always obvious when you’ve powered it on and then off again by holding down the button a bit too long.

The Gardenwatch Cam does a decent job. It creates AVI format movies. It has 7 interval settings ranging from 1 minute to 24 hours. It has two focus settings, one for close up, and one for landscape.

With the monarchs, though, I want to be able to get in closer, and have sharper images than the Gardenwatch cam will give me. I still have a Nikon D70 which served me well for many years, but has been supplanted by the D90 in recent years. I also have a small assortment of lenses that I’ve accumulated over the past fifteen years. I’m thinking that the six megapixels of the D70 should be far more than adequate for doing some nice macro time-lapse work.

So the only problem is intervalometry — how do I trigger the camera to take pictures? Nikon sells intervalometers for most cameras, but the D70 is notably excluded from that list. There are a number of people making kits (or generously giving away their designs). I thought I might be able to rig something together.

I was successful. Taking an ancient Gateway Solo 9300 notebook that I’d bought for a king’s ransom back in 1998 or 1999, I installed Ubuntu 11.4 desktop on it. This was a mistake. The machine has a 366MHz Pentium II processor, and 128 MB of memory — lesser specs than your iPhone2. It got part way through the boot sequence, and locked up (terminal swapping? driver issues? I don’t know). I then installed a version of Ubuntu 8 Server for which I happened to have a CD. After installation, I booted into Matrix-esque screen garbage, but after some fighting with boot parameters was able to get running cleanly. Next, I installed gPhoto2. Putting the D70 into PPT mode, I hooked it up to the notebook with a USB cable.

Voilà! Now, all it took was a few commands:

Find the camera:

gphoto2 --auto-detect

Store pictures on the camera’s compact flash card:

gphoto2 --set-config capturetarget=1

And take pictures at a 30-second interval:

gphoto2 --capture-image --interval 30

If I get any worthy results, I’ll post ’em on Archie’s Garden.

1 There sure are a lot of great insect words. “Eclose” and “chrysalid” are just two among many.
2 The two generations of iPhone had 128 MB of memory, and a 412 MHz ARM processor.


Tue, 2 Aug 2011

Bug hunting rig

— SjG @ 8:18 pm

I’ve had a few requests on Flickr to document what I’ve been using for bug hunting.

Well, here it is. Nikon 105mm f/2.8 macro, 36mm (and/or sometimes 24mm) Kenko extension tube(s), and Nikon R1 close-up flash system. I’ve been shooting mostly hand-held, 1/200 sec at f/10-f/22. I make up for hand shake by taking three or more pictures for each one I even consider keeping.

20110802-091758.jpg

20110802-091814.jpg


Thu, 10 Dec 2009

Nikon D90 anomaly

— SjG @ 1:58 pm

So in the middle of taking a set of pictures, I noticed that my D90 was not actually saving the pictures I took. The mirror would flip up, the shutter would click, but the display would show the same older picture again.

I tried the usual suspects. Turning the camera off and on. Changing the directory on the card where files were supposed to save. Swapping out memory cards. Reformatting memory cards. Doing the two-button reset. Doing the menu reset. Pulling out and then replacing the battery.

I could shoot a picture with a blank memory card installed, and the display would say “Folder contains no images.”

I searched on the internet for this symptom, and found no other reports of it.

Here’s what finally cured it:
* switch into LiveView mode
* take a picture – this will fail
* take another picture – this will succeed
* switch out of LiveView mode

Et voila! Now it works. I don’t know if this is reproducible, nor if I’m just heading down a path toward permanent issues, but I figured it would be worth posting just in case anyone else has the same issue.


Tue, 13 Jan 2009

Combat

— SjG @ 3:54 pm

Seen on the way in to work this morning. Only had my Canon Powershot with me… so, it’s just another reminder to always bring the big camera with big glass at all times.

Semi-aerial combat

Semi-aerial combat