Views of UIImagePickerController
The standard image capture in API in the iPhone SDK is the UIImagePickerController. There is much discussion on the web about how this can be customized via subclassing, both from the viewpoint of technical feasibility, and from the viewpoint of being allowed onto the AppStore. It is generally accepted that going direct to private frameworks is unacceptable, even though this arguably can give a better user experienced. Phanfare had their app pulled from their AppStore for using the PhotoLibrary private framework, and returned with a new version that instead customizes the UIImagePickerController experience.
I took an in-depth look at the view structure that the standard UIImagePickerController creates. The first is obtained by looking at self.view and is not particularly interesting. It consists of a UITransitionController and a UINavigationController and is clearly the meta-system for switching between the capture and preview screens.
The second view hierarchy is created by PLCameraController, and can be obtained by implementing willShowViewController in the UINavigationControllerDelegate. The first callback to this comes when UIImagePickerController wants to display a PLCameraController. The view hierarchy is much more interesting:
Several of these classes are undocumented, but that doesn’t prevent us from manipulating them with standard APIs. Experimentation showed that the UIImageView highlighted in red is the important one - it’s the camera preview pane. You can remove every other view, and just retain this one, and you will get a full-screen camera view. You can also move the TPPushButton (which represents the cancel button) out of the hierarchy and place it elsewhere on the screen. Doing the same with the TPCameraPushButton causes a crash when you activate the button, because the PLCameraController tries to modify the buttons, and fails because the view structure has changed.
You can also add further views (as Phanfare did) to overlay extra details. Clearly there is yet more scope for customizing other aspects of the hierarchy - this requires more experimentation, and we’ll report on this as we learn more.
November 11th, 2008 at 3:00 pm
Subclassing UIImagePickerController…
I’m trying to modify the UI that the user is presented with when they’re taking a picture. Specifically, I want to remove the “Take Picture” title bar and replace it with a custom graphic.
I can cr……
November 11th, 2008 at 3:16 pm
[...] The Air Source placed an observative post today on Views of UIImagePickerControllerHere’s a quick excerptThe standard image capture in API in the iPhone SDK is the UIImagePickerController…. [...]
November 11th, 2008 at 3:33 pm
[...] The standard image capture in API in the iPhone SDK is the UIImagePickerController. There is much discussion on the web about how this can be customized, both from the viewpoint of technical feasibility, and from the viewpoint of being .. More [...]
November 16th, 2008 at 9:49 am
Is the UIImageView really the cam preview? I onlly get the closed iris view when I grab its image. Or does one have to initialise the camera first?
November 18th, 2008 at 4:14 pm
I haven’t yet figured out how to grab the image, but it’s definitely the cam preview - if you remove just that view from the superview, then you get no camera preview at all.
November 19th, 2008 at 4:06 pm
Ben,
thanks for the info. I did my own “investigation” and came up with the same view hierarchy, although, I must say that the ImageView *is* the Iris. So far I have this: PLCameraView has four subviews:
0: ?;
1: is the UIImageView (iris);
2: ?;
3: all the extra stuff. So to get a full screen preview, with nothing else, you only have to remove that last view (the PLCropOverlay). I tried getting the content of view 0 and 2, but only got black screens so far.
November 19th, 2008 at 4:10 pm
sorry, view 0 (first subview) is the cameraPreview, but rendering its content leads me to only a black screen
November 19th, 2008 at 4:13 pm
I think we need to trade some code. I’ll get my code up later this week.
November 19th, 2008 at 5:59 pm
ok, I got it… I know why I’m only getting a black screen: it’s because renderInContext is limited to only render some parts, not all.
November 19th, 2008 at 7:48 pm
That’s where I got to - black screen with renderInContext, yet I could swear I was grabbing view 1, not view 0. I’ll have to check when I’m back on the mac.
November 20th, 2008 at 1:13 am
Rolando - you’re absolutely right. My apologies; I obviously got my ordering wrong when going from my code to a PNG graphic. I’ve corrected the blog post.
November 24th, 2008 at 10:36 pm
Ben, I finally was able to grab the screen
I’ll put my code online once I clean it up a bit.Btw, the iPhone camera sucks for scanning barcodes in real time
November 24th, 2008 at 11:14 pm
Awesome. Look forward to seeing it! The iPhone camera sucks quite a lot, never mind just for barcodes!
November 27th, 2008 at 5:04 pm
Ben, here’s a proof of concept: http://www.youtube.com/watch?v=uc-p221SQ0g, code to follow soon…
December 8th, 2008 at 6:18 pm
Rolando, any code to share yet??
December 10th, 2008 at 12:36 am
Amazing, thank you so much.
December 12th, 2008 at 12:06 am
I’m on the same track (just finished playing with the various camera picker subviews and layers before I found this page), if I get any code to work soon that manages to read the preview image I’ll post as well.
It would be a very nice thing to take to an iPhone Dev Camp I’m attending this weekend…
December 18th, 2008 at 3:02 pm
Any thoughts on how to use this to capture the event generated when the shutter button is pressed? I’d like to be able to trigger a function when the view changes to the preview view…
December 18th, 2008 at 3:07 pm
Tom - Sure. Add an action to the TPCameraPushButton.
December 18th, 2008 at 3:45 pm
It would be great to see some demo code…
December 18th, 2008 at 9:59 pm
Sweet, that works nicely. Thanks…
December 18th, 2008 at 10:01 pm
Tom - great
December 22nd, 2008 at 12:02 pm
Hi.
is it possible to grab a frame from incoming video and access the raw RGB data of the frame with this approach ?
December 22nd, 2008 at 6:40 pm
It’s certainly possible, the questionis whether you can do it with a legal API or not. Rolando says it’s possible, and we’re hoping to see some example code from him at some point.
December 23rd, 2008 at 2:47 am
Yes, it is possible with hacked toolchain, but it’s not desirable.
If we can get the raw image data through the official SDK, it will be great.
I am really looking forward Rolando’s sample code.