Thursday, February 24, 2011

Recording Animations via HDMI

I've gotten some questions about how the video in my recent animation article as well as the video of Romain's excellent photo viewing app were created. I thought I'd spend a few words on it in case anyone else wants to do something similar.

I can tell you how I did it, but it'll cost you. About $200, in fact; that's how much I paid Amazon for the setup I used.

First, the reasons I wanted the device:

  • Debugging animations is hard: So many of the issues I chase with animations are timing-dependent. So the typical approach of step-debugging doesn't work; as soon as you stop in the debugger, you've lost the stream of whatever is causing the issue.. Nor does it help to hack the code and add tracing output everywhere, because sometimes you can't easily access the code in question (although this is what I end up doing in many cases where I can change the code). Sometimes it helps to dramatically sloooooooow down the animations, so that you can see it unfold instead of trying not to blink and miss the action. But what would be really nice is to be able to catch the actual animation, at speed, and then be able to see it played back in slow motion. That's what HDMI recording gives me. I thought about getting a high-speed camera, but between the cost, the reliance on a lot of light for each frame, and the setup for any shot, that didn't seem like a great general solution.
  • Screencasting: I've been wanting to do more blogging about Android development. In particular, I'd like to post some video tutorials, something like I did in a previous life. I find that forum to be very efficient, once I get into the groove. I can talk through a demo, show the demo, and show the code, and do so in far less time than it takes me to write an article, for example. But that means I'll need some way to screencast from the device that's running the animation code that I'll be talking about. I could take a video of me playing with the device, but it's more of a hassle to set it up, and the quality of the video just isn't as good.

The solution: an HDMI recorder. The Xoom device on which I recorded the video has an HDMI output port. So all I needed was a device on the other end of the HDMI cable to record that output stream. I picked up an Intensity Pro PCI Express card by Blackmagic, and that did the trick. I installed the card in my Mac Pro, installed the software that came with the device, and it was a simple matter of running the capture software to capture the actual video stream. You can also use other capture software, such as Adobe Premiere, but I found the software that came with the device sufficient for my needs. I did notice an occasional dropped frame (I had to set a setting in the software to not stop recording when there is a dropped frame), but overall it seems fine, at least for my use cases.

Here's a picture of the recorder's box (the card is in my machine and I didn't feel like taking it out). I like the sheer recursiveness here: it's a picture taken with the device of the recorder, uploaded via HDMI from the device to the recorder. I've put some other completely random objects on the shelf with it to give you a sense for its size (small).

I'm sure there are other solutions out there, but this setup works for me.

Animation in Honeycomb

I've posted an article, Animation in Honeycomb, on the Android Developers blog. The article gives an overview of the new property animation system in Android 3.0. Check it out.

And while you wait, here's the demo reel for the article. I wanted to show some of the home screen interactions and API demos from the SDK that take advantage of the new animation framework. The sound track has nothing whatsoever to do with Android, but the video seemed to want audio. It was a sound decision.

Wednesday, February 16, 2011

Flex 4 Fun: The International Tour

The international book tour for Flex 4 Fun began last November in Antwerp, Belgium (the home of diamonds, chocolate, and GUI toolkit programming books). It was a gray a rainy day, which is unusual for Antwerp except for the months between September and June.

The tour began as all such things do: parties dripping with scantily-clad programming celebrities, mobs of teeming fans fighting for autographs and shreds of clothing, and all-night hacking orgies. It was unforgettable, it was a blur of over-caffeinated memory, it was ... just another book tour.

The tour came to an abrupt end. I can't confirm that it was because of overcrowded venues and rabid crowds that overwhelmed Interpol forces. I can only say that I had to leave the town anonymously, quickly, and with only 10 pounds of chocolate as a memory of the experience.

Or...

I gave a talk on Flex 4 Fun at Devoxx. The presentation gave an overview of some of the graphics and animation features in Flex 4, and worked through an example of skinning a component to show some of these new features. This was one of several talks I gave that week, although this was the only one on Flex. In fact, it's probably the last such talk, since I don't have a lot of opportunity to do Flex development in my new Androidal life. Call it my final Flex fling ... 4 fun.

Instead of embedding the video, I'll encourage you to go to Parleys.com to watch the presentation, and to check out the many other videos from the Devoxx conference. Parleys has a subscription model (79 Euros to watch all videos from Devoxx 2010), but there are a few talks available for free now (like this one) to whet your appetite.

Enjoy the video while I continue to recover from the tour.

Saturday, January 15, 2011

CodeDependent: The Clothing Line

(Cross-post with my humor blog; I figured this content would wear well on my geek blog, too).

For no good reason at all, I decided that geeks need more T-shirts and that I need to provide them. Fortunately, I don't have to pit my sewing skills against such a high goal; I'll just let CafePress do it for me.

Here's the first such effort, especially topical for this blog, "codedependent" (available in various colors/styles - see the site for the full array):

Tuesday, January 4, 2011

Video: Reflections on Android

Everyone's supposed to make a resolution on New Years, so here's mine: post more articles/blogs/videos about Android development. Starting with today's video tutorial.

Here's the first in what I hope will be a series of video tutorials on anything ranging from graphics to animation and back to graphics (hey, it's my show and I might as well talk about the things I enjoy).

For the Devoxx conference last November, I developed a simple picture-viewing application to demonstrate various facets of UI development that Romain Guy and I were talking about that week. You can see the presentations online at parleys.com (you'll have to register for 79 Euros to get access to them for now). But I wanted to deep dive into particular aspects of this application for my blog. Here's the first of these tutorials, in which I talk about the simple reflection effect used in the application. By the way, credit for the beautiful pictures goes to Romain, my source for all of my, er, borrowed images.

The video is in two parts (because YouTube thinks that I talk too much, so I had to split it). This first part introduces the show and talks about the effect at a high level:

Part 2 dives into the code that makes the reflection effect work:

The code in the video is a tad blurry (given the resolution of the video compared to the size of the IDE window), so here's the code from PictureView.java that I walk through for your reading pleasure (note that this code looks slightly different than that in the video due to formatting for a smaller line wrap. Also, the blurryBitmap image is now created to be only as high as the reflection height, as described in the comments):

private Bitmap getReflection(Bitmap bitmap) {
    Bitmap reflection = reflections.get(bitmap);
    if (reflection == null) {
        // We're cropping the height of the reflection to 80
        int reflectionH = 80;
        reflection = Bitmap.createBitmap(bitmap.getWidth(),
                reflectionH, Bitmap.Config.ARGB_8888);

        Bitmap blurryBitmap = Bitmap.createBitmap(bitmap, 0,
                bitmap.getHeight() - reflectionH,
                bitmap.getWidth(), reflectionH);
        // cheap and easy scaling algorithm; down-scale it, then
        // upscale it. The filtering during the scale operations
        // will blur the resulting image
        blurryBitmap = Bitmap.createScaledBitmap(
                Bitmap.createScaledBitmap(
                        blurryBitmap,blurryBitmap.getWidth() / 2,
                        blurryBitmap.getHeight() / 2, true),
                blurryBitmap.getWidth(), blurryBitmap.getHeight(), true);
        // This shader will hold a cropped, inverted,
        // blurry version of the original image
        BitmapShader bitmapShader = new BitmapShader(blurryBitmap,
                TileMode.CLAMP, TileMode.CLAMP);
        Matrix invertMatrix = new Matrix();
        invertMatrix.setScale(1f, -1f);
        invertMatrix.preTranslate(0, -reflectionH);
        bitmapShader.setLocalMatrix(invertMatrix);

        // This shader holds an alpha gradient
        Shader alphaGradient = new LinearGradient(0, 0, 0, reflectionH,
                0x80ffffff, 0x00000000, TileMode.CLAMP);

        // This shader combines the previous two, resulting in a
        // blurred, fading reflection
        ComposeShader compositor = new ComposeShader(bitmapShader,
                alphaGradient, PorterDuff.Mode.DST_IN);

        Paint reflectionPaint = new Paint();
        reflectionPaint.setShader(compositor);

        // Draw the reflection into the bitmap that we will return
        Canvas canvas = new Canvas(reflection);
        canvas.drawRect(0, 0, reflection.getWidth(),
                reflection.getHeight(), reflectionPaint);
    }
    return reflection;
}

And finally, here's the Eclipse project complete with source code, images, and everything you need to build and run the application. The app is targeted at Android 2.2 (Froyo) (and probably could work on earlier versions as well), so you should be able to run it on the emulator or any appropriate device. Note that it's just a demo and not really a full-featured photo viewer; it was written to demonstrate particular effects and techniques, not to be a real application.

Now that my New Year's resolution is fulfilled, I should go back to working on Android framework code...

Thursday, December 2, 2010

Slides from Recent Android Presentations

Here are slides for two of the approximately 871 talks that Romain Guy and I gave at Devoxx last month (and again at the SF Android User Group meeting a couple of days ago).

Videos of all of the Devoxx sessions are already posted on the excellent Parleys site for a small subscription fee, and should be made freely available sometime in the next few months. You probably want to check out those videos for the complete details. But in case you were at the talks, are sick of listening to us speak, or simply want to peruse the slideware, here you go...

Android Graphics and Animation

Android UI Development: Tips, Tricks and Techniques

Saturday, November 27, 2010

Flex 4 Fun 4 Kindle

By popular demand, Flex 4 Fun is now available for the Kindle!

If you order the eBook on the Artima site, you can download the Mobi as well as the PDF version. In fact, if you already bought the eBook, you can log into your Artima account and download the new Mobi version. Once you have the .mobi file, you can copy/email it to your Kindle device and start reading.