The Extra Mile: Adding the Web Cam

So I had less than two hours left, and I wanted to attempt the really fun part: the streaming webcam. A typical webcam will create a new image -- say, myimage.gif -- every second or so. It will then copy that image to a public Web server.

Since MIDlets can only display graphics using the PNG file format, I figured that all I had to do was convert myimage.gif, on the fly, to myimage.png. At the same time, I could strip out the color information and reduce the image so that it fit on the tiny 110x85 screen. By making the image as small as possible, it would be possible to retrieve each frame in minimal time.

Of course, I didn't have time to do any of this. So I just converted and resized a few images by hand and put them up on a server. The images were a series of a young girl, looking into her webcam, smiling and talking.

I'd figured that this part would be pretty easy. After all, I could just use the createImage method and point it to the URL in question. But it didn't work like that. The createImage method allows you to load up a local PNG, for example:

createImage(String filename);

And it allows you to create an image from a byte array:

createImage(byte[] imageData, int imageOffset, int imageLength);

But it doesn't allow you to input a URL as a parameter.

Figure 3. Figuring out how to serve the webcam images to the mobile phone was frosting on the cake. Somehow, it worked on the first try.

There are other methods in the MIDP Connector class that let you retrieve a URL. But then what? You can't exactly download the image, store it on the hard drive, and then load it up again. After all, there is no hard drive on a cell phone. And Java's security sandbox forbids storing foreign files directly in memory.

I was about to give up. After all, there was only about an hour and a half left and I thought I had a reasonably cool Home Control app. But I couldn't see any way of getting the image off the server and squeezed into the phone. So I went and got a massage.

The masseur was a hell of a nice guy, very talkative, into yoga, art, raves, and other nifty San Franciscan things. He also did wonders to my every joint and muscle, not missing a spot.

As I wobbled away from the chair, I had a stupid, crazy idea. I realized that while it wasn't easy to download an image directly, I could download the binary contents of the image file. I could then feed that byte array directly into the createImage method. It took about a half hour, but I came up with something like this (it definitely wasn't commented or formatted as nicely!):

I tried it out and somehow, I'm not sure how, it worked. First try!

Now I had to tie it all together. I quickly hacked together an inner class called VideoTimer, which called a nextImage() method every few milliseconds:

Conclusion

The contest was over. I went home and tried to sleep, but my brain was still in heavy programming mode, with Java code leaking behind my eyeballs like sheets of rain on a window. I thought of all the cool features I couldda, shouldda, wouldda added: multiple camera configurations, smart device detection, image conversion on-the-fly, and a more robust and dynamic menu system.

The next day I received a call: I was one of the top six finalists, and would I kindly present my app to a panel of judges? The presentation happened quickly, and I remember it in a blur. The audience and judges seemed to appreciate the home automation part, but they really liked the streaming webcam. I think seeing a live image flicker on the tiny screen may have helped open up many people's imaginations, helping them realize that all this talk about Java and embedded systems isn't hype -- not all of it, at least.

When they announced me as the winner, I was in awe. I was happy for the prize. But more so, it was exciting for me to affirm that by focusing, preparing, and persisting you can use today's technology to make very cool things happen in very short amounts of time.