Detecting iPad Mini Hardware

I spent some time tracking this down today. I ended up modifying this UIDevice+Hardware category from the iOS Developer Cookbook by Erica Sadun.

The proper "hw.machine" value for the WiFi iPad Mini is "iPad2,5". The GSM & CDMA version of the iPad Mini will likely be "iPad2,6" and "iPad2,7", though I don't have one of those to test with. This blog post appears to have at least some empirical evidence of the former.

Here is the relevant snippet:

if ([platform hasPrefix:@"iPad1"])              return UIDevice1GiPad;
if ([platform hasPrefix:@"iPad2,5"] ||
    [platform hasPrefix:@"iPad2,6"] ||
    [platform hasPrefix:@"iPad2,7"])            return UIDeviceiPadMini;
if ([platform hasPrefix:@"iPad2"])              return UIDevice2GiPad;
if ([platform hasPrefix:@"iPad3"])              return UIDevice3GiPad;
if ([platform hasPrefix:@"iPad4"])              return UIDevice4GiPad;

The full diffs are available in this fork of Erica's code.

Timbre Connects Local Musicians With iPhone Users

Great writeup of the story of how Timbre came to be. I was interviewed for this one.

Responsive elements that retain their aspect ratio

A bit non-intuitive that padding-bottom: 50% would be relative to the element's width.

Preventing "Blurry Images" in Silverlight Printing

When printing a bitmap from a Silverlight 4 application, sometimes the result can be a little bit blurry. For many applications this is acceptable, but in the case of this StackOverflow question, the blurry result means that the QR code being printed can no longer be read.

It's easy to understand the cause of the bluriness. When Silverlight 4 prints, it takes a UIElement and rasterizes it to a bitmap at a resolution suitable for printing (typically 600 DPI). Since screen resolution is around 96 DPI, the Silverlight printing routine will "upscale" bitmaps in the UIElement. By default, this upscaling operation uses linear resampling, which results in blurred edges (especially between black and white pixels).

In WPF, it's possible to override the type of scaling done so that the blurred edges don't occur. The attached property RenderOptions.BitmapScalingMode exists for just this purpose. Unfortunately, that is not available in Silverlight. There is a workaround, however -- you can do the scaling yourself, and apply a ScaleTransform to the image that exactly offsets your scaling. When the PrintDocument goes to "upscale" to 600 DPI, it will essentially just be removing that ScaleTransform, resulting in your original image.

To demonstrate, we can start with a checkerboard image that's generated with a WriteableBitmap:

int width = 40;
int height = 40;
double checkerSize = 4;
int stride = width;

WriteableBitmap bitmap = new WriteableBitmap(width, height);

for (int y = 0; y < height; y++)
{
    for (int x = 0; x < width; x++)
    {
        if (Math.Floor(x / checkerSize) % 2 ==
            Math.Floor(y / checkerSize) % 2)
            bitmap.Pixels[x + stride * y] = 0xFF << 24; // Black
        else
            bitmap.Pixels[x + stride * y] = 0xFF << 24 | 
                                            0xFF << 16 | 
                                            0xFF << 8  | 
                                            0xFF; // White
    }
}

Image image = new Image() { Stretch = Stretch.None };
image.Source = bitmap;

PrintDocument printDocument = new PrintDocument();
printDocument.PrintPage += (s, args) =>
{
    args.PageVisual = image;
};
printDocument.Print("Checkerboard");

On screen, here is what the bitmap looks like:

original

Here's what it looks like when printed:

printed

You can see that the edges of each square are blurred. To get rid of the blur, we first scale up our image to 600 DPI (from 96 DPI), then apply a ScaleTransform that exactly offsets the scaling:

int width = 40;
int height = 40;
double checkerSize = 4;

double scale = 600.0 / 96.0; // scale from 96 DPI to 600 DPI
width = (int)(width * scale);
height = (int)(height * scale);
checkerSize *= scale;

int stride = width;

// Same code to create the checkerboard...

Image image = new Image() { Stretch = Stretch.None };
image.Source = bitmap;
image.RenderTransform = new ScaleTransform
{
    ScaleX = 96.0 / 600.0,
    ScaleY = 96.0 / 600.0
};

This time when we print, the result has sharp edges:

crisp

Un-blur Photoshop filter unveiled at MAX

It appears to be a two-step process; first, you figure out the blur kernel, then you use that kernel to unblur the image. The white line in the blur kernel represents the path of the camera while the shutter was open, and consequently it's a map of how a single pixel gets "smeared" to create the blur.

The second step seems fairly straightforward. Standard blur features like gaussian blur use a kernel to spread the value of a single pixel to its neighbors (that's called "convolution.") With a known kernel, a similar convolution could get the original image back.

The magic here is the first step -- creating the blur kernel directly from an already-blurred image.

The Architecture of Open Source Applications

Architects look at thousands of buildings during their training, and study critiques of those buildings written by masters. In contrast, most software developers only ever get to know a handful of large programs well—usually programs they wrote themselves—and never study the great programs of history. As a result, they repeat one another's mistakes rather than building on one another's successes. This book's goal is to change that.

TermKit: WebKit-based unix terminal

The interface ideas here are brilliant, e.g. the auto-complete, and ls with proper icons. I'm not sure webkit/javascript/json is the proper implementation though, and the author has a few misconceptions about unix; cat isn't just for displaying the contents of a text file, it's for concatenation. The implementation of cat as an all-purpose file viewer doesn't quite fit.

JavaScript Typed Arrays

Toward better binary data handling in JavaScript. I like the buffer/view abstraction.