Tue, 25 Oct 2011

Thoughts while reupholstering

— SjG @ 9:31 pm

It’s time to reupholster the kitchen chairs. They’re just (relatively) cheap Ikea chairs, but it seems like it’d be a waste to pitch them just because the non-replaceable cushions have become stained and/or faded. I figured I’d reupholster them myself. I’d never done this before, but how hard can it be?

So I found myself in the office, using a few homemade implements to loosen hundreds of staples, and then pincers to pull ’em out. Quacky (the cat; formally addressed as Daphne) kept interrupting. She evidently found the activity irksome, insofar as it did not involve petting her.

The new fabric color is an orangey, stripey color (not unlike Quacky), and as I worked my mind wandered about pumpkins and other symbols of the season.

Why is it, I wondered, that October brings not only a proliferation of Halloween decorations, but also the appearance of Christmas decor? After all, there’s another significant holiday betwixt. Is the reason thematic? Well, perhaps, I concluded, but not really. Halloween is superficially about spookiness and perhaps confronting mortality, but it’s really an excuse to break out of the humdrum, to escape normal standards of behavior, to don costumes, to go mad with decorations, and for adults to drink and children to overindulge in candy. Christmas as celebrated here is ostensibly a religious holiday (and again, a chance to confront concepts of mortality), but it’s really observed more as an orgy of gift-giving/gift-receiving, a chance to wear silly reindeer hats to the office, an excuse to go mad with decorating, and a justification for adults to drink and for children to overindulge in candy.

I had finished removing the staples, and using the old fabric as a template, I traced out the shape on the replacement fabric, and cut my new portion. Then, after giving Quaky a few minutes of petting, I got back to work, stretched the new fabric over the foam and tried to make sure it all lined up correctly.

OK, so both Halloween and Christmas provide a justification to behave differently. They are both holidays about consumption, whether in the “buy a whole lotta decorations” or the candy/alcohol sense. But that forgotten holiday centers around feasting as well: Thanksgiving is a well known opportunity to overindulge. So why are stores filled with Christmas stuff instead of the chronologically more appropriate Thanksgiving stuff? After all, you can decorate for Thanksgiving too — many of us have fond memories of making cut-out paper Pilgrims in their belted hats and turkeys in elementary school. Why not turkey and corn yard decorations?

By now, I was trying to secure the new fabric, and my staple-gun kept jamming. I had to disassemble it twice to remove mis-fed staples that had gotten twisted up inside the mechanism. And when it worked, each thwack of a staple going in would startle Quacky, and she gave me a doleful yellow-eyed glower.

So is Thanksgiving less of an event because of our discomfort about what likely befell the Native American hosts of the first Thanksgiving? Elementary school pictures always had happy “indians” partying with the Pilgrims — it wasn’t until later, that we wondered if those were the same “indians” who fought against the cowboys. And it wasn’t until much later when we ventured into A People’s History that we got anything like the actual story.

Or is Thanksgiving not a such a great marketing opportunity because it’s ostensibly about appreciating what we have? It may be hard to sell gratitude as a consumable product. I personally find gratefulness to be a powerful emotion, and a positive influence on my day to day mood. I keep a list with me, entitled “important things,” where I occasionally jot down small circumstances for which I’m grateful. At one point, Elizabeth and I had a bound book where we planned to write down daily gratitudes: unfortunately, that seems to have gotten lost in the shuffle. Perhaps a rigid schedule is not the right approach, but I think the idea still has merit. Still, bound books or no, it’s going to be a lot harder to sell gratitude gear at WalMart than it will be to sell realistic brain-dripping lawn zombies or battery-powered Santa Clauses.

I finally got the fabric stapled down, and one chair finished. It was an amateurish job, but not bad for a first try. Quacky looked more than a bit skeptical, but I’m optimistic that the next three will be better.

Filed in:

Fri, 21 Oct 2011

Using PHPExcel with Yii

— SjG @ 2:18 pm

I was running into problems with conflicting autoloaders when I tried to use PHPExcel with the Yii framework. There are instructions out on the web on how to resolve this, but they are only useful if you’re not creating instances of Yii active record models while you’re using PHPExcel. That’s fine if you’re using Yii to create an Excel spreadsheet from already instantiated Yii classes, but my need is to read an Excel spreadsheet and import its data into my database.

It turns out that this is fairly straightforward as well. The trick is in realizing that PHPExcel is registering its autoloader when it’s instantiated, so you don’t need to register it yourself.

public function actionImport()
  $message = '';
  if (!empty($_POST))
    $file = CUploadedFile::getInstanceByName('import');
    $spec = Yii::app()->basePath.'/data/imports/'.$file->name;
    spl_autoload_register(array('YiiBase', 'autoload'));
    try {
         $inputFileType = PHPExcel_IOFactory::identify($spec); 
         $objReader = PHPExcel_IOFactory::createReader($inputFileType);  
         if ($inputFileType != 'CSV')
        $objPHPExcel = $objReader->load($spec); 
        $objWorksheet = $objPHPExcel->setActiveSheetIndex(0);
        $highestRow = $objWorksheet->getHighestRow();
        for ($row = 1;$row < $highestRow+1; $row++)
             $myObjThing = new MyObject; // Yii AR model
             $myObjThing->someField = $objWorksheet->getCellByColumnAndRow(1, $row)->getValue();
             $myObjThing->otherField = $objWorksheet->getCellByColumnAndRow(5, $row)->getValue();
             $myObjThing->detachBehaviors(); // PHP < 5.3 memory management
    catch (Exception $e)
       $message = 'There was a problem handling your file. Technical details: '.$e->getMessage();
    if (! empty($message))

Pretend WordPress didn’t hose the formatting on that …

Tue, 18 Oct 2011

Publishing Old Projects

— SjG @ 9:52 pm

I’ve been publishing a bunch of old projects that I may have posted here, or simply left on my hard drive to suffer the slings and arrows of outrageous bit-rot. Most of these are projects that I created for some specific purpose or another, and have either coded to the point where I’m satisfied with them, or abandoned them.

I’m publishing this stuff in the hopes that it’ll be useful to somebody somewhere. In some cases, the code’s primary use may be as an example of how not to accomplish a task. In other cases, they’re projects that are being used in mission-critical operations, and so are reasonably robust.

I’ll be maintaining them on GitHub, if you want to get creative with the definition of “maintaining.”

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)

will cause random crashes, but
for (var i in someCollection)

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.

Sat, 24 Sep 2011

Ffun ffmpeg ffunctionality

— SjG @ 2:59 pm

I’ve been processing a collection of product videos which came to me in a huge variety of sizes, aspect ratios, and qualities. I need to re-encode them to work in HTML 5, but, more importantly, I need to make them fit into a common player space on the web page.

It turns out that newer versions of ffmpeg support not only cropping, but also padding, and you can even do both operations at once!

For example, I had a source video that was originally 16:9, but had been letterboxed to 4:3, and then had two different sets of labels added. I needed to crop out the letterboxed portion and the top set of labels, and make the result fit nicely into 16:9. So I used VLC, a screen capture utility, and Photoshop to get the measurements. Then I used ffmpeg to crop the relevant section and pad it out to fit into my space (in this case, I’m left aligning the video in the padded output):

ffmpeg -i original/converted.wmv -vf crop=394:295:6:0,pad=524:295:0:0:0xFFFF00 -sameq

That’s cropping a 394 x 295 piece out of the original video (with the origin at 6 pixels from the left, and 0 pixels from the top), and then padding it out to 524 x 295 filling the padded area with bright yellow. The 524 x 295 is really close to 16:9 — and in a later process, it gets resized to the more standard 480 x 2721.

You can string together the padding and cropping in either order, depending on the effect you’re trying to achieve.

1I’m sure some educated person out there could tell me why video standards are so confused/confusing, down to the non-square pixels. While a true 16:9 would dictate 480 x 270 pixels, everybody seems to use 480 x 272. Why? The only thing I can figure out is that 272 is evenly divisible by a power of 2, which probably made display hardware cheaper to manufacture. As you can see, my resizing adds a bit of distortion, but at these resolutions, it doesn’t really matter.