Cocoa in the Shell

Images dimensions in QuickLook

I’m often looking for images dimensions, and most of the time I hit the spacebar to trigger QuickLook to see them, and each time I’m disappointed because it only displays the name of the file, which, we TOTALLY do NOT care. Finally I end up opening the image with Preview, just for some dimensions, it’s teh sux. So it was time to create a new Xcode project.

The default behaviour when you QuickLook an image looks like this

Having the name of the file as the window title is, in my opinion, totally useless.

So, after creating the QuickLook project, I took a look at QLGenerator.h, and find this useful line of code :

QL_EXPORT const CFStringRef kQLPreviewPropertyDisplayNameKey; // useful to customize the title of the QuickLook panel

Awesome, just what I needed.

Now finding the images dimensions is trivial with ImageIO, so let’s implement GeneratePreviewForURL().

OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options)
{
    CGImageSourceRef imgSrc = CGImageSourceCreateWithURL(url, NULL);
    if (!imgSrc)
    {
        QLPreviewRequestSetURLRepresentation(preview, url, contentTypeUTI, NULL);
        return -1;
    }
    CFDictionaryRef imgProperties = CGImageSourceCopyPropertiesAtIndex(imgSrc, 0, NULL);
    CFRelease(imgSrc);
    if (!imgProperties)
    {
        QLPreviewRequestSetURLRepresentation(preview, url, contentTypeUTI, NULL);
        return -1;
    }
    CFNumberRef w = CFDictionaryGetValue(imgProperties, kCGImagePropertyPixelWidth);
    int width = 0;
    CFNumberGetValue(w, kCFNumberIntType, &width);
    CFNumberRef h = CFDictionaryGetValue(imgProperties, kCGImagePropertyPixelHeight);
    int height = 0;
    CFNumberGetValue(h, kCFNumberIntType, &height);
    CFRelease(imgProperties);

    CFStringRef keys[1] = {kQLPreviewPropertyDisplayNameKey};
    CFStringRef values[1] = {CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%dx%d"), width, height)};
    CFDictionaryRef properties = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    QLPreviewRequestSetURLRepresentation(preview, url, contentTypeUTI, properties);

    CFRelease(values[0]);
    CFRelease(properties);

    return noErr;
}

Ok, we are almost done, we need to implement the GenerateThumbnailForURL() function, otherwise all images icon will become generic. Luckily, it’s only one line of code :

OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize)
{
    QLThumbnailRequestSetImageAtURL(thumbnail, url, NULL);
    return noErr;
}

Let’s take a look at the result :

Ok, that’s more like it.

I put the Xcode project on my github.

For non-devs, here is a direct link to the plugin.

To install it, simply unzip the file and place qlImageSize.qlgenerator in your /Library/QuickLook or /Library/QuickLook folder.

To force QuickLook to reload the plugins open Terminal.app and type :

qlmanage -r

EDIT 1: I added the file size.

EDIT 2 :

If you build from the sources, I added an option to display the image extension inside the icons in the finder. The extension is based on the Uniform Type Identifier (UTI) of the image.

Tags: