Scribbler’s Image Editing Opensourced Part 1
Well since I no longer work at the NHS I’ve been working really hard on one of the great features of Scribbler, image editing. As something I wanted to put in at the very start, I was really enthusiastic to start using Apple’s Image Kit. It promised developers the chance to do very little work and still have fully-fledged image management, provided by IKImageBrowser (very good) and image editing thanks to IKImageView. Unfortunately, the latter does not live up to the hype. After battling with it for a while and trying to justify to myself that it would suffice for version 1.0 of Scribbler, it was just way too incomplete, buggy, and damn ugly to leave in. I try to work with the idea that if it bugs me, it’s not good enough.
Image Loading
Let me start with IKImageView. It loads images ok, although larger images aren’t loaded nicely: they’re drawn incrementally in a really jarring fashion, even if you pass the view a CGImageRef that’s already in memory. That being said, it does handle quite a few different types of images, so we give it half a point.
Image Editing
The main function of such a view is not for viewing images, but for editing them within the application. Many users want to quickly change an image they’re working with and then get straight back work. Taking our cues from iPhoto we guess that this editing will take the form of colour adjustments rotating and cropping. If we’re feeling really generous, then we can also include a straightening tool and some zooming (although the latter is relatively superfluous unless we have some sort of pixel-level editing like iPhoto’s red-eye removal or the touch-up tool).
So we’ve put IKImageView in our app, and loaded an image, we then want to change the brightness and contrast, so we double-click on the image and open up the shared instance of the IKImageEditPanel (left).
Compared to iPhoto’s panel (right), this is ridiculously ugly, has no icons, has an Aqua button at the bottom instead of a properly-rendered HUD button. The biggest issue: it appears off-screen all the freaking time. Can you imagine editing a bunch of images and having to manually drag the panel to where you want it each time you open the damn thing up? No amount of setting the frame of the window or teaching it to autosave it’s position fix this, and even if we could, the first time you run the app it’s at the bottom of the screen with most of it hidden.
Lastly, you just try setting a new image in the view and getting the edit panel to do anything anymore, as far as I can tell -reloadData is a no-op, it neither reloads the data for the panel, nor makes you more attractive. The only way to fix this is to close the panel, and reopen it (and then moving it so you can see the controls).
Rotation
If we want to rotate the image we (in code) select the IKToolModeRotate mode and we get our onscreen compass:
The problem with this is two-fold: click on the image at about 3/4 the way up and the rotation compass is drawn outside the bounds of the view; secondly, the user interaction is all wrong. To rotate you click and hold ok the image and move the mouse around in a manner that’s so hard to control it’s useless. Then think about saving the image after a rotation. The view itself has no concept of a canvas, so we can’t save an angled image on a white background, and we can’t arbitrarily decide to ignore the user’s rotation setting an save an un-rotated image (rock – me – hard place). Basically the tool is broken and doesn’t provide useful functionality to users.
Cropping
Then we have IKToolModeCrop. “Fantastic!” I hear you cry. “No longer will my users have to open up another app to crop an image, and I won’t have to write that code”. You diligently select a region if the image, then call -setCurrentToolMode: and….
Nothing. Nada. Zip.
Reading through the programming guide tells us that Apple have declared the mode and not implemented it (apoordesignersayswhat). So we then have to do it, but can we get the selection rectangle? Of course we can’t! So that nice crop button we made goes to waste, unless you want to subclass, track the mouse, interrupt -drawRect:, apply the crop using core image (note to all that CICrop filter is not a magic bullet), draw a CGImage with the cropped version, then reset the image. No thanks. On it’s own that might be fine, but with all the other rubbish in this class you’re starting to flog a dead horse.
So that’s why IKImageView will *not* be making an appearance in Scribbler, and if you find it in any other apps then… well… I heard that Windows Photo Viewer Deluxe Family Millennium Media Edition is fantastic.


David Allen Parizek Jr 20:59 on February 28, 2009 Permalink |
So what did you turn to instead?
I am finding I have the exact same dilemma. I am more of a newbie though, and was now attempting to figure out how to do it elsewise by reading Programming with Quartz (Glephman, Laden) to get a clue and then thought I would go hunt for a Cocoa open source project I could mimic code from.
David Allen Parizek Jr 21:01 on February 28, 2009 Permalink |
What is vImage? It is mentioned as a tag, but their are no other posts on this site tagged that way, and no mention of it in the article…
umm, nevermind, google says:
http://developer.apple.com/documentation/performance/Conceptual/vImage/Introduction/chapter_1_section_1.html
David Allen Parizek Jr 21:19 on February 28, 2009 Permalink |
This being open source might help someone trying to add image editing features and figure out best way to do it sans IKImageView:
http://seashore.sourceforge.net/index.php
Jonathan 21:20 on February 28, 2009 Permalink |
Hi David,
Yeah so my solution is in the works at the moment. As part of Scribbler I’ve written my own image-editing view. As soon as I’m content that it’s working correctly then I’ll open it up.
vImage is cool.
Jonathan 21:23 on February 28, 2009 Permalink |
The problem with Seashore is the license. GPL is no good to me. When I’m done ESImageView (as it’s called) will be BSD.
David Allen Parizek Jr 06:21 on March 1, 2009 Permalink |
Here we go, sample from apple, it is sweet as far as doing what I need:
http://developer.apple.com/samplecode/Cropped_Image/index.html#//apple_ref/doc/uid/DTS10000388
David Allen Parizek Jr 06:23 on March 1, 2009 Permalink |
RE: above post, running the sample app is great, not sure how to get the pbx files updated to XCode… XCode does not want to deal with them, but can still look at all the code…
David Allen Parizek Jr 06:33 on March 1, 2009 Permalink |
Ok, it is an old pbx example. To get in to XCode just create new XCode project and add most all of the sample’s files into your new project and it built for me no problem.
Jonathan 11:55 on March 1, 2009 Permalink |
That’s a really interesting example actually, thanks David. I’ve implemented selection and crop in a completely different way, drawing my selection rect over my image with a CGLayer, then using the CGLayer as a mask so I can create a composite CIImage with the area that would be lost in crop processed with a blur filter. I’ll have to have a good look at this and see how well it works for large images.
Also, all you need to do is change these old .pbproj files to .xcodeproj and xcode will handle them fine
Thanks again, you’ve given me food for thought.