2012年7月1日 星期日

Custom Camera Applications Development Using Iphone Sdk

iPhone contains many useful features. One connected with these people is build-in camera along with Camera application method to make photos. It seems to be great although why don't you consider camera consumption with local applications? iPhone SDK delivers the actual potential of utilizing camera through UIImagePickerController class. Thats fantastic but the good news is modest disadvantage - you should not create a full-screen prolonged are living digital camera watch like the Camera software does. Instead connected with which you have to employ UIImagePickerController only throughout modal method - indicate this pop-up modal watch when you have to have a shot and in close proximity the actual look at once the actual shot is made. You have got to reopen this kind of view once again to adopt the next one.

Moreover, that modal perspective contains extra panels and adjustments this overlay the camcorder view. Another negative aspect is definitely - you can not take a image with one touch; you need to contact the Shoot switch to consider a photograph and also preview it, and then it is advisable to hint the actual Save press button to get the image for processing. Probably its the top perform but I dont want it and also I desire you think the same way.



What concerning while using UIImagePickerController as an ordinal non-modal view controller underneath this navigation controller the same way as we create a savings fund other view controllers? Try the item and you may discovered that it works! The video camera look at is effective as well as appears while it should. You can easily assign a delegate in addition to practice UIImagePickerControllerDelegate events to acquire in addition to conserve this photo. Ok, effect the particular Shoot button, feel that Save press button - great, youve bought the photo! But o nly look at the following - your Retake and Save buttons stay above the actual photographic camera view, and they dont operate these days when they will be touched This is usually books can not totally reset the actual view for taking a different photo following getting a single along with coming in contact with the Save button, the view is definitely freezed as well as the switches are usually disabled. It feels you'll need to help fully recreate the particular UIImagePickerController instance to take another photo. Thats not therefore very simple but not and so good. And you continue to have to utilize the panels and switches that overlay the actual photographic camera view



Now I have a strong idea! When most of us touch Shoot, the view prevents refreshing as well as exhibits sole photo through the camera; then you'll find in order to touch Retake or even Save button. Can most people get in which image and spend less the idea devoid of with the UIImagePickerControllerDelegate and in that case touch your Retake mouse programmatically to totally reset that view and have yet another photo? Sure we can! If a person check out your video camera landscapes hierarchy right after pressing Shoot you'll find that there's a invisible view involving ImageView type. This class isn't described inside SDK, nevertheless most people could check out it is methods implementing Objective-C capabilities. We could see how the elegance boasts a system called imageRef. Lets try this Yes, that income CGImage object! And this impression size is usually 1200 times 1600 - it's absolutely the camcorder picture!



Ok, right now all of us find out you can easlily find the photograph without UIImagePickerControllerDelegate. But within just what exactly second should all of us perform this? Can many of us pick up a computer owner touches about the Shoot p ress button for you to begin processing? Its doable however , not hence good. Do you recall our main purpose producing the on going full-screen camcorder watch for instance procedure Camera program does? Its time period to try and do it! When most of us dived around the views hierarchy, weve identified that you'll find quantity of vistas earlier mentioned the digital camera view. We might try to disguise these landscapes and also make our own switch listed below this camera check out to look at the actual photo around one particular touch. But how must all of us induce this digicam view to generate the actual photo? Its quite easy - we are able to find the related selector from the Shoot button as well as name that out of our action handler!



Ok, weve forced obtaining the image. But requires people couple of seconds. How might all of us detect that this photo will be ready? It happened when the Cancel as well as Shoot buttons are generally changed by mean s of Retake plus Save ones. The most basic strategy to detect this particular is definitely starting a timer along with quick time period and viewing the buttons. And and then we could get and save the particular photo, with the corresponding selector in the Retake press button and also calling that to be able to reset the digicam view and also prepare yourself this to generate a new innovative one. Here will be code:



// Shot option around the toolbar touched. Make the actual photo.
- (void)shotAction:(id)sender {
[self enableInterface:NO];
// Simulate hint for the Image Picker's Shot button
UIControl *camBtn = [self getCamShutButton];
[camBtn sendActionsForControlEvents:UIControlEventTouchUpInside];

// Set upward timer to check the particular video camera handles to detect if your image
// through the camera will possibly be prepared.
// Image Picker's Shot switch is flushed seeing that userInfo in order to r eview together with current button.
[NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(savePhotoTimerFireMethod:) userInfo:camBtn repeats:NO];
}

// Return Image Picker's Shoot button (the mouse in which creates the photo).
- (UIControl*) getCamShutButton {

UIView *topView = [self findCamControlsLayerView:self.view];
UIView *buttonsBar = [topView.subviews objectAtIndex:2];
UIControl *btn = [buttonsBar.subviews objectAtIndex:1];

return btn;
}

// Return Image Picker's Retake button that looks following user pressed Shoot.
- (UIControl*) getCamRetakeButton {

UIView *topView = [self findCamControlsLayerView:self.view];
UIView *buttonsBar = [topView.subviews objectAtIndex:2];
UIControl *btn = [buttonsBar.subviews objectAtIndex:0];

return btn;
}

// Find the particular view which contains this camera settings (buttons)
- (UIView* )findCamControlsLayerView:(UIView*)view {

Class c / list = [view class];
NSString *desc = [cl description];
if ([desc compare:@"PLCropOverlay"] == NSOrderedSame)
return view;

for (NSUInteger post = 0; i < [view.subviews count]; i++)
{
UIView *subView = [view.subviews objectAtIndex:i];
subView = [self findCamControlsLayerView:subView];
if (subView)
return subView;
}

return nil;
}

// Called through the timer. Check the camera controls to identify the fact that picture is actually ready.
- (void)savePhotoTimerFireMethod:(NSTimer*)theTimer {

// Compare existing Image Picker's Shot button with passed.
UIControl *camBtn = [self getCamShutButton];
if (camBtn != [theTimer userInfo])
{
// The button succeeded through Save option - the actual photograph is ready.
[self saveImageFromImageView];

// Simulate touch on Retake button to continu e on working; that camcorder can be ready to take brand-new photo.
camBtn = [self getCamRetakeButton];
[camBtn sendActionsForControlEvents:UIControlEventTouchUpInside];

[self enableInterface:YES];
}
else
{
NSTimeInterval period of time = [theTimer timeInterval];
[NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(savePhotoTimerFireMethod:) userInfo:camBtn repeats:NO];
}
}

// Save used image through hidden photograph view.
- (BOOL)saveImageFromImageView {

UIView *cameraView = [self.view.subviews objectAtIndex:0];
if ([self enumSubviewsToFindImageViewAndSavePhoto:cameraView])
return YES;

return NO;
}

// Recursive enumerate subviews to uncover concealed image watch plus help save photo
- (BOOL)enumSubviewsToFindImageViewAndSavePhoto:(UIView*)view {

Class cl = [view class];
NSString *desc = [cl description];
if ([desc compare:@"ImageView"] == NSOrderedSame)
return [self grabPictureFromImageView:view];

for (int post = 0; i < [view.subviews count]; i++)
{
if ([self enumSubviewsToFindImageViewAndSavePhoto:[view.subviews objectAtIndex:i]])
return YES;
}

return NO;
}

// Grab the image from concealed image look at and also help you save that photo
- (BOOL)grabPictureFromImageView:(UIView*)view {

CGImageRef img = (CGImageRef)[view imageRef];
if (img)
{
// Taken impression is at UIImageOrientationRight orientation
UIImage *photo = [self correctImageOrientation:img];
UIImageWriteToSavedPhotosAlbum(photo, nil, nil, nil);

return YES;
}

return NO;
}

// Correct image alignment from UIImageOrientationRight (rotate about three months degrees)
- (UIImage*)correctImageOrientation:(CGImageRef)image {

CGFloat bigger = CGImageGetWidth (image);
CGFloat peak = CGImageGetHeight(image);
CGRect bounds = CGRectMake(0.0f, 0.0f, width, height);

CGFloat boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;

CGAffineTransform transform = CGAffineTransformMakeTranslation(height, 0.0f);
transform = CGAffineTransformRotate(transform, M_PI / 2.0f);

UIGraphicsBeginImageContext(bounds.size);

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextScaleCTM(context, - 1.0f, 1.0f);
CGContextTranslateCTM(context, -height, 0.0f);
CGContextConcatCTM(context, transform);

CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), image);

UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return imageCopy;
}



Another significant question is: with what moment might all of us stash the particular overlaying digital camera sights and equipment and set up our individual button? Trying the actual viewDidLoad Oops The video camera view remains to be not necessarily created. Trying your viewWillAppear The exact same thing Trying that viewDidAppear Yes, the particular vistas have already been made and may be disguised . now. Ok, we obscure in which and create a toolbar with each of our Shoot button. It works, women and men screen flicks - we see what sort of standard landscapes as well as buttons are found along with then hidden. How could we stop this? I tried several approaches along with acquired determined the most beneficial one: we ought to hide your views prior to these are extra into the video camera view (when the addSubview method associated with that photographic camera look at can be called). Its doable usi ng Objective-C power that will upgrade the method dynamically at run-time. Ok, lets substitute your addSubview by our very own method. In our technique you can easlily look at which the actual handed down watch will be one of several photographic camera watch subviews in addition to arranged its concealed home to help YES. So, we replace your addSubview in that viewWillAppear before that camcorder view is definitely created. And we make our toolbar along with Shoot switch around your viewDidAppear after this video camera check out is created. Take a look at the particular value below:



// Replace "addSubview:" whenever identified as first time; cover digital camera controls otherwise.
- (void)viewWillAppear:(BOOL)animated {

[super viewWillAppear:animated];

if (toolBar != nil)
{
// The perspective has been witout a doubt appeared; most of us don't really need to subclass UIView
// but ought to disguise added camcorder controls.
UIView *cameraView = [self findCamControlsLayerView:self.view];
if (cameraView)
{
cameraView = cameraView.superview;
int cnt = [cameraView.subviews count];
if (cnt >= 4)
{
for (int i = 2; i < cnt - 1; i++)
{
UIView *v = [cameraView.subviews objectAtIndex:i];
v.hidden = YES;
}
}
}
}
else
{
// Subclass UIView along with substitute addSubview in order to hide the particular digital camera watch adjustments about fly.
[RootViewController exchangeAddSubViewFor:self.view];
}
}

// Exchange addSubview: involving UIView class; collection our own myAddSubview instead
+ (void)exchangeAddSubViewFor:(UIView*)view {

SEL addSubviewSel = @selector(addSubview:);
Method originalAddSubviewMethod = class_getInstanceMethod([view class], addSubviewSel);

SEL myAddSubviewSel = @select or(myAddSubview:);
Method replacedAddSubviewMethod = class_getInstanceMethod([self class], myAddSubviewSel);

method_exchangeImplementations(originalAddSubviewMethod, replacedAddSubviewMethod);
}

// Add the subview that will view; "self" tips on the parent or guardian view.
// Set "hidden" in order to YES if the subview is actually the video camera controls view.
- (void) myAddSubview:(UIView*)view {

UIView *parent = (UIView*)self;

BOOL carried out = NO;
Class cl . = [view class];
NSString *desc = [cl description];

if ([desc compare:@"PLCropOverlay"] == NSOrderedSame)
{
for (NSUInteger when i = 0; i < [view.subviews count]; i++)
{
UIView *v = [view.subviews objectAtIndex:i];
v.hidden = YES;
}

done = YES;
}

[RootViewController exchangeAddSubViewFor:parent];

[parent addSubview:view];

if (!done)
[RootViewContr oller exchangeAddSubViewFor:parent];
}



The technique described earlier mentioned ended up being employed in iUniqable program available from Apple App Store (Social Networking section). Feel free to use.



Feel free of charge to see this website belonging to the designer www.enterra-inc.com



???????

沒有留言:

張貼留言