Home  |  software  |  Musings  |  Pictorial  |  Academics  |  Links


Utilitage For Your Drawage

Due to popular request, below are my image conversion and utility routines, expanding on this earlier post. The one that people ask for regularly is the caching CIContext stuff used to speed conversion of a CIImage to an NSImage or CGImageRef. There's nothing particularly tricky about it, basically, you just make the context on the fly as needed and if it needs to be bigger, you create a new one, but you never make it smaller. Easy-sleezy, McFreezy!

So there's code here to go from CIImage to a premultiplied bitmap buffer, CIImage to an unpremultiplied bitmap buffer, CIImage to a CGImage. There's code to simplify creating a bitmap CGContextRef you can use for rendering something that's destined to go to the screen (it just wraps the CoreGraphics stuff and uses settings suitable for to-screen drawing). There're RGB <-> HSV conversions, which are rather skanky and not at all optimized.

And finally, there's a bunch of stuff to help with resolution independence. If you want to use PNGs instead of multi-image TIFFs, you can just name your PNGs with "MyImage.png" (for 1x), "MyImage_1.25.png" (for 1.25x), "MyImage_2.png" for (2x) and so on, and grab the most suitable one for a given scale factor with two calls.

There's also a selector that gives you the "best" CGImageRef for the image at a given filesystem path, given a known scale factor for that image and the scale factor you want to display the image with. This does a bunch of computation and heuristics based on the image's pixel dimension and DPI metadata and scales it if necessary, but tries not to.


Clickie for

Rescuing Mail.app Orphaned Emails

So for absolutely no good reason, I just selected my main inbox in Mail.app, went up to the Mailbox menu and chose to Rebuild the mailbox. And boom, everything after January of 2006 disappeared. Not very nice, Mail.app!

Here's how I got my emails back. This is seriously not for faint of heart. Seriously. And any arbitrary update to either the operating system or to Mail.app might break my instructions. And it's a pain in the ass. And this is only for POP email, no clue how things work with IMAP. And you need to have Apple's free Developer Tools installed. And these instructions are only for Intel machines. And your problem is probably something different anyway.

Tiling an Image Using CoreGraphics

Still more sample code! This one shows how to create a tiled pattern starting from a CGImage. One could also use this to create a CGColor out of the generated pattern.

Clickie for the code

Converting a CIImage to a Bitmap

Someone on Apple's OpenGL mailing list asked about converting a CIImage into a pixel bitmap. This is harder than one might think, and there are a bunch of ways of doing it. Here's one. I'm posting it here because the mailing list has a lame 18Kb size limit and this code was too big for the list.

Another way of doing this is with glReadPixels. I don't think that's a good way because it means that the CIImage needs to be rendered into an OpenGL context (moving it to the GPU and possibly doing a data transfer on the GPU) and then copied back into system memory. I think the technique below stays on system memory and never hits the GPU.

If you need to do this conversion often, you should cache the CIContext and the CGContext and regenerate them only if the image becomes larger - creating them is very expensive in my experience. I'll be glad to post code that caches if you'd like, I just pulled the caching out for what is below. Please leave a comment if you'd like me to add that — I pulled that out of my code to post this simpler version.

If you plan to modify the pixels, you'll probably want to unpremultiply them first. You can use vImage to do this. And if the image is intended for something other than the screen, you should change the colorspace. And don't forget to free the returned buffer — you own it.

Clickie for The Code

Update: I've posted the version with caching here

Unified Toolbars and Sucky Themability

Windows with a unified toolbar are not very nice to theme, unfortunately. In fact, the phrase "<expletive> brain dead" comes to mind. The brief synopsis is that you should probably just not try to theme them. If you leave 'em unthemed, ShapeShifter (as of version 2.4b4) will automatically use the title and toolbar of a metal window for you, while still giving you the drag-by-toolbar functionality that distinguishes the unified toolbar. This is almost certainly what you wanted anyway. But if you insist on being masochistic, continue on…

There are three resources that control the appearance of the unified toolbar. In ThemePark, these are located at:

  • Elements -> Global Elements -> Windows (Aqua) -> Window Background
  • Elements -> Global Elements -> Windows (Unified) -> UnifiedBackground (Short)
  • Elements -> Global Elements -> Windows (Unified) -> UnifiedBackground (Tall)

When the window is frontmost, the two UnifiedBackground resources are used. Otherwise, the titlebar and toolbar are tiled with Window Background. Right off the bat, that's annoying to theme — filling the titlebar and toolbar with the pattern that you intended for the background of the window content is nasty.

Also, both of the UnifiedBackground elements contain two different states. You'd assume (if you were possessed of that "sanity" thang) that the first is for the active window, while the second is for the inactive. Nope. In almost all cases, only the first state is used. The second is used only when the Unified window is frontmost, but there is a modal dialog in front of it, as seen in the picture below.

Non Main Window

But it gets worse. You may have noticed that the resource titled Short is 80 pixels tall, while the element titled Tall is 62 pixels, well, short. Yeah, I don't know either…

Moving on to the actual implementation, the two images are composited on top of each other with varying degrees of transparency in order to form the unified background. Here's how it all works:

Toolbar Contents Short Opacity Tall Opacity
Large Icon with Text 0 1
Small Icon with Text 0 1
Large Icon Only 1 0.984
Small Icon Only 1 0.855
Large Text Only 1 0.677
Small Text Only 1 0.661

Yeah, I'm not sure what the rationale behind this weird implementation is, either.

But it gets worse. These UnifiedBackground elements are stretched rather than tiled. This implies two things right off the bat - if you want the titlebar portion or your titlebar-toolbar combo to always look a particular way, you're screwed - if the user changes the toolbar size to small icons rather than the large icons you were using when you designed things, all of a sudden, she'll have a squashed looking titlebar. Yucky.

This also means that you're pretty much limited to using a solid color horizontally, since this 8-pixel wide image gets stretched all the way across the window including inside of the left and right caps.

So basically, your theme can duplicate Apple's implementation of unified, and that's about all you can realistically do.

Here are a few screenshots showing how this all works.

UnifiedBackground (Short) UnifiedBackground (Tall)
Large Icon and Text
Large Icon with Text
Large Icon Only
Large Icon Only
Small Text Only
Small Text Only

So, yeah, leave these unthemed and let ShapeShifter do the work for you.


© 2005 — All Rights Reserved Site credits >