Archive for tag: coding

The wedding photo booth – part two

As promised, this is my follow-up post on our DIY wedding photo booth.  I'll probably do one more where I go into more detail about the code, but this will cover the integration of the pieces, starting with the software.

As mentioned before, I wrote a custom application to run on my netbook.  Basically, I wanted it to be very easy for everyone to use, so I basically limited the interface to "Press a key to continue" kinds of interactions.  If you watch the video, you can see a complete demo I recorded tonight.

Photo booth application demo


Of course, one of the critical components was going to be the camera.  Photo booths are not known for great photography, so we didn't need something too high-end, but we did want decent images.  Since I could use my discount at the company store, I got the MS LifeCam Cinema.  In hindsight, I should have gone with the LifeCam Studio since it can be mounted on a tripod, but the Cinema worked well enough.

I wrote the software so that it would print out the guest's photos on a 4x6 photo paper when they were done.  To do that, we needed a decent photo printer.  After a little bit of research, we settled on the Canon PIXMA MG5220.  Of course, immediately after I bought it, I started seeing them for less than I paid, but that's just life, I suppose.  In any case, we couldn't have been happier with how it worked out.  It prints great photos and it holds enough paper that it didn't have to be constantly reloaded throughout the night.

Lighting was another problem to solve.  We weren't sure what the light levels were going to be like at the hall, so we needed to find some way to ensure enough light in our booth.  It took a while, but we finally found some clip-on lights at Target that would do the job.

Lighting in the booth

They look pretty bright here, but we used low wattage bulbs so we wouldn't blind our guests as they were having their pictures taken.  As you can see, the netbook is setup on a small table in the booth.  The printer sat on a table outside the booth so a new guest could get their picture taken while the previous guest waited for their prints.

Thanks again to Amber's mom, we also covered some of the exposed PVC pipe with sleeves so they would look better in the photos.  You can see them better in this picture:

Sleeves

We didn't get a really good shot of the booth completely assembled at the wedding, but here's the best one so far:

The booth at the wedding

And of course, my favorite picture:

Amber and me post ceremony

Everything turned out really well, but of course if we had it to do again, I'd probably make some changes.  The main thing would have to be the color of the fabric.  It was just a little too dark, which made the lighting that much more difficult.

It was a fun project and everyone seemed to really enjoy it at the wedding.  There were 175 sets taken all told, including retakes.  Some of these strained the capacity of the booth, but they turned out great.

20110722210921

20110722232513

We couldn't have done it without help from Amber's mom, Vicky, and our good friend Teri who kept an eye on the booth throughout the night to make sure it ran smoothly.  Thanks again!

The wedding photo booth – part one

It's been more than a month since the wedding, but Amber and I are still frequently reminiscing about how beautiful and great everything turned out and how much fun we (and hopefully our guests) had.  There is so much to share that I'm sure I'll do at least a couple more posts, but tonight I'm going to talk about something we made for the reception that I'm particularly proud of: our wedding photo booth.

First, a little back story: Amber and I have a fondness for photo booths.  I'm not sure how it started, but when we encounter a photo booth, more often than not, we get even more sappy than usual and get some pictures.  They aren't always the best pictures, but they are fun.

france seaworld beach engagement photo booth

save the dateAs you can see, we even used one for our save the date cards.  We enjoy them so much that we thought it would be great to have one at our wedding.  Amber did some research (she did most of the leg work for vendors) and found that it would be pretty expensive to rent one, so I decided to take it on as a DIY project.

I have a netbook that I received as a bonus from work that I figured could be used to run the software.  For printing the pictures, I needed to find a decent photo printer - the printer I had wasn't up for the task.  A good webcam was the only other hardware that would be required.  Of course there was the matter of constructing the booth itself, but I figured we could build a simple frame of some sort and cover it with drapes.  I figured that I could probably do it all (given the components that I had on hand) for about $250.

Part of the reason I wanted to do the project was to give myself a coding project to work on.  I'll do another post going into specifics on this part, but I ended up building a Silverlight application to simplify the webcam integration and to do some animations in the UI without too much effort.  I spent many hours coding and testing the application so that it was relatively easy to use for the most novice computer users among our guests.  I have many pictures like this from these sessions:

testing

And a few like this:

more fun testing

All work and no play makes Jack a dull boy, after all.

The next step was to plan and build the booth.  It needed to be portable and quick and easy to setup.  I figured that I could do construct a frame with PCV pipe pretty easily.  I thought about it and decided that I should probably prototype with some stuff around the house, just to get my mind going on how it would go together.  After some tinkering and a quick trip to the office supply, this is what I came up with:

Prototype

As you can see, I constructed my prototype from disposable pen tubes and paperclips.  I misread the number of pens in the package I bought, so I couldn't complete the prototype, but it allowed me to visualize how things would go together and the couplings I would need to buy.  I tried to find these at home depot, but they only carried the standard plumbing connections, elbows and tees, but not the three-way connections for the corners or the four-way connections for the middle back.  Fortunately, Amber in her research found an article by someone that had done something similar (silly me, I didn't look at it until after I did my prototype) that referenced a site where you could mail order the joints I needed.

The next step was to purchase the PVC and somehow get it home and cut.  For those of you who haven't purchased PVC pipe, it is sold in ten foot sections.  Given the length of the pipe and the number of pieces I would need to cut it into, I figured I'd need a friend with power tools and a truck.  While I waited for one of my friends with such equipment at their disposal, I happened to talk to my dad about the project and he suggested that PVC is really quick to cut with just a hacksaw and I could do it in the parking lot if necessary to fit it in the car.

Things were already behind schedule and I was eager to get this part done, so I figured what the hell, and Amber and I went to Home Depot to give it a shot.  We purchased our PVC and were surprised to find that with my back seats folded down, we could fit the ten foot PVC pipe in my two-door Honda Accord!  They went all the way from the back of the car into the passenger seat and on the dash, but all nine pieces fit.

Once we got it home, I started cutting.  Fortunately, my dad was right and the hacksaw made very quick work of the PVC.  I marked the pipe with painter's tape and scored the pipe with a file so I'd get relatively straight cuts. Marking PVC

Scoring Cutting

Initially, I planned on having every section of pipe be uniform and planned on cutting four foot sections, essentially stacking one cube on top of another with a shared edge, but once I started putting things together, it became clear that an eight-foot tall booth was going to be too much.

Construction Construction

Fortunately, since I was cutting two four-foot sections out of the ten foot pipe, I had two foot left over from each pipe.  So the top section became two foot tall, for an overall height of six foot.  Much more manageable.

Completed

The next task was covering the booth.  I'd planned on using curtains, but unfortunately, we couldn't find ones that were reasonably inexpensive, that were reasonably opaque and would fit.  After several trips to stores looking for some or an alternative like sheets, we gave in and went to a fabric store to see what we could find.  After dealing with a few surly and non-helpful employees, we found just enough fabric on clearance that met our criteria.  Amber's mom was instrumental for this part, as we don't own a sewing machine and I haven't operated one since junior high.  It turns out that she is a master.  We took the frame down to Maple Valley, and she knocked out the panels in no time flat.

Sewing

We really couldn't have done it without her help.  We kept one of the curtains we tried as the door.  Here's the finished booth.

Covered

This post has obviously turned into a novel, so I'm going to stop here for tonight.  In the next part, I'll write about integrating the components.  In the meantime, here's one last picture: Amber and me in the finished booth at the reception.It worked!

Latest comments navigation issue resolved

Fixed another issue on PardonMyReach this morning.  The latest comments navigation on the right was showing an unexpected order for the comments and wasn't getting the latest ones.  It turns out that the XSLT that generates this content had a sort bug in it.  Here's the original code:

image

If you click on it to make it actually visible, you might spot the bug.  The key for the sort, @created, is actually a datetime, but the sort is treating it as a string and sorting it alphabetically.  Here's my fixed XSLT:

image

It turns out that each comment also has a sequential id, so I used that for my sort key, marked it as a number, and it works.

Some other possible solutions:

  • Parse the string into substrings (year, month, day, hour, minutes…)and sort appropriately.  I didn't do this because it looks like the string that represents the datetime created is not using fixed-width fields ("9/5/2010 11:35:23 PM" and "10/26/2010 10:08:09 PM" were demonstrate this), so it looked more challenging to do this.
  • Use XSLT 2.0 and specify these values as dates.  I didn't do this because I wasn't able to easily confirm Umbraco support for XSLT 2.0.  (A quick search on the forum indicated that it supports 1.0, but this may have changed.)

Tag issue resolution

imageAs I mentioned back in Tag filtering, anyone? I have solved the issue I found on my blog with posts not being included when using the tag filtered navigation.  Tags were being correctly counted on the navigation (shown right), but if you clicked on one of these links, only some of the appropriate posts would show up.

I should start with a little more background in case you haven't been following PardonMyReach.  I'm using Umbraco 4.5.2 and the blog4Umbraco package.  I had a really easy time getting Umbraco setup and the blog4Umbraco package installed, but there were a number of minor issues that I discovered with my new blog as I started using it, the aforementioned tag filtering issue being one of them.  Most of the time, I use Live Writer to create my posts.  I noticed that the blog posts that I was posting using Live Writer weren't included when I used the tag filtering navigation.

So one workaround (which I later found mentioned on some of the forums) would be to open each post in the Umbraco back office website for my blog and save it, which seemed to correct the issue, or simply to use the back office to create my posts in the first place.  Neither of these options was particularly appealing, so I kept looking into it.

imageIn examining the database where my content is stored, I found a table suspiciously named cmsContentXML.  Each row has two fields, intuitively named nodeId and XML.  In looking at the XML, I noticed a difference in the XML between posts.  Shown right are two such examples.  (Yes, I am lazy and just did a little image capture - someday I'll get around to writing a style for displaying code clearly in the blog.)  You'll notice that the <tags> element is actually empty (at least for all intents and purposes) on the second post.  Sure enough, when I filtered based on the appropriate tag, the second post was omitted.  Ah ha!

So for some reason, the tags weren't getting saved in the content xml in the DB when I posted using Live Writer, but the count of posts by tag were actually correctly displayed.  I also noticed in the DB that there are two other tables, cmsTags and cmsTagRelationship.  cmsTags is a mapping of tag ids to tags.  cmsTagRelationship is a mapping of content nodes to tags.  And this table was correct.  Just to see if this issue was likely an issue with the blog package or Umbraco, I created a new document type with a tag property and tried creating some content with the back office and with Live Writer and found the same result.  So I concluded the issue is actually in Umbraco and not the blog4Umbraco package.  I spent a little time looking through the Umbraco source, but the issue wasn't obvious to me and I wasn't really all that excited about patching the CMS, so I turned my attention to trying to work around the issue in the blog4Umbraco code.  (It's also possible that this is deprecated functionality and the tag relationship should be determined from the tags library instead of the content node, but this seems a little inconsistent with the other properties).

After looking at the code, I decided the easiest thing to do would be to fix up the content node.  So I looked at creating an event handler.  In blog4Umbraco, there are already several defined, so I opened up BlogDateFolder.cs and added an event handler of my own:

image

(Sorry again about the formatting on this - I guess I'll have to look into displaying code more clearly.  Actually, I tried to post this as code wrapped in a <pre> tag, but it caused an error.  More issues to look at…)

As you can see, I found that the umbraco.editorControls.tags.library.GetTagsFromNodeAsITags() method correctly returns the tags associated with a node.  So I created a BeforePublish event handler and wired it up in the constructor of BlogDateFolder.  The method Document_BeforePublish_Tag does the real work.  In this method, I simply get a list of tags using GetTagsFromNodeAsITags(), create a comma delimited string of tags from this list, and reset the empty tagProperty.Value to the string I create. 

I liked the idea of making this a BeforePublish event handler since it both fixes new posts from here on forward and also allows me to fix the existing posts simply by republishing my content tree.

I could probably clean this up quite a bit.  Firstly, I should probably use a string builder for better performance.  And I could also check to see if the tags need fixing in the first place.  I could also pull this out of blog4Umbraco and create a separate package that would allow a user to configure which ContentTypes to fix (in case they have more than just BlogPost that they care about).

Working on my blog vs. actually writing

me I probably should be doing something else right now - riding the exercise bike or getting ready for work, but instead I decided to write a quick blog post as I sit here, enjoying my morning coffee.  (Okay, this is not really a picture of me today, but I am enjoying my coffee in it.)

When I showed Amber the fix I made last night for the tag filtering, it prompted her to ask if I was having fun fixing up the issues I've found with the blog.  After some hesitation, I replied, "um… yes, kinda…"  (Not my normal witty repartee, I admit.)  It is fun, but it can also be frustrating.  I get frustrated with the lack of written documentation on Umbraco.  Sure, there are a mountain of how-to videos that have great content, but I can read really quickly, so I'd really like more written content.  There are forums and wikis, but sometimes it is hard to find what you are looking for.  And I'll admit that I'm reticent to post on forums.  I don't know why.  Maybe that is something I need to work on.

The fun parts for me are finding the bugs, coming to an understanding of the cause and eventually fixing them.  It's a puzzle to solve and you learn in the process.  In researching the fix for the tag issue, I eventually downloaded the source code for Umbraco 4.5.2 and Blog4Umbraco and figured out how to compile and package the latter.  I figured out more about Umbraco under the covers and now understand most of the Blog4Umbraco code.  I can install it on my local server and debug issues.  I've made changes and pushed them to my live site.  So I feel a certain sense of accomplishment there.  Maybe sometime I'll start pushing issues to the Blog4Umbraco community and suggesting fixes.

What is a little annoying is the amount of time I've spent building and fixing PardonMyReach as opposed to actually writing.  But eventually I think that will swing the other way as I get these fixes addressed and only have a backlog of new features I'd like to add.  And I really am going to write up more technical details of the fixes and changes I make, so that will be more content too, right?

P.S. for those of you who might have been waiting for a follow up on my Halloween post, our final tally was a record 40 trick-or-treaters this year.