UIImagePickerController having issues even after declaring from the Appdelegate - iphone

we are doing a photo application in which UIImagePickerController is used. For maintaining only one instance of the controller we have declared it in the appdelegate. But even after doing that memory leak is still there. Can any one please help us
Here's our code
In AppDelegate.h
UIImagePickerController *imagePicker;
#property (nonatomic, retain) UIImagePickerController *imagePicker;
In AppDelegate.m
#synthesize imagePicker;
and in applicationDidFinishLaunching event
imagePicker = [[[UIImagePickerController alloc] init] autorelease];
Need to call this UIImagePicker in CameraView
In CameraView.h
RedDawnMediaAppDelegate *appDel;
#property (nonatomic, retain) RedDawnMediaAppDelegate *appDel;
In CameraView.m
#synthesize appDel;
and in viewDidLoad
appDel=(RedDawnMediaAppDelegate*)[[UIApplication sharedApplication] delegate];
appDel.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
// Hide the camera controls:
appDel.imagePicker.showsCameraControls = NO;
appDel.imagePicker.navigationBarHidden = YES;
appDel.imagePicker.delegate = self;
// Make the view full screen:
appDel.imagePicker.wantsFullScreenLayout = YES;
appDel.imagePicker.cameraViewTransform = CGAffineTransformScale(appDel.imagePicker.cameraViewTransform, CAMERA_TRANSFORM_X, CAMERA_TRANSFORM_Y);
// Now incert our overlay view (it has to be here cuz it's a modal view):
appDel.imagePicker.cameraOverlayView = overlayView;
[self presentModalViewController:appDel.imagePicker animated:YES];
in didFinishPickingMediaWithInfo
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[appDelegate.imagePicker dismissModalViewControllerAnimated:YES];
uploadImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[uploadImage retain];
NSData *imageData = UIImageJPEGRepresentation(uploadImage, 0.5);
//[uploadImage release];
UIImage *image=[UIImage imageWithData:imageData];
self.view.frame = CGRectMake(0, 0, 320, 480);
self.wantsFullScreenLayout = YES;
objCameraImageView = [[CameraImageView alloc] initWithNibName:#"CameraImageView" bundle:[NSBundle mainBundle]];
[objCameraImageView setParentController:self];
objCameraImageView.cameraImage = image;
[image release];
uploadImage = nil;
[self.view addSubview:objCameraImageView.view];
[self release];
}
After taking a photo we are showing the preview in another view. so we are invoking the Cameraview for several times which is leading to Memory leak pls help.

First of all you dont need to worry about maintaining only one instance of imagepickercontroller. Getting an image from camera is much simpler than what you are doing.
See my post here:
How to take picture from Camera & saved in Photo Gallery by programmatically?
since Im releasing the picker when its done getting the image. There wont be memory leak!

Related

Updating Button image once is selected iPad not working

I am trying to make my image update once a new on is selected.
The update works but it does not show up right away when the new image is selected during editing and I was wondering if anyone has any idea how to fix it.
The app was originally created for iPhone and this function works fine, the image is updated as soon as a new one is selected even during editing for the iPhone, but when I use it on the iPad the image does not change during editing but once I finish the editing and go back, I can see the image is change.
I am making the core data recipe sample code from the developer center to work on the iPad.
This is my code for selecting a new Image PhotoTapped1 button, this has been change to work with the iPad:
- (IBAction)photoTapped1 {
if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone){
// If in editing state, then display an image picker; if not, create and push a photo view controller.
if (self.editing) {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
[self presentViewController:imagePicker animated:YES completion:nil];
[imagePicker release];
} else {
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
recipePhotoViewController.hidesBottomBarWhenPushed = YES;
recipePhotoViewController.recipe = recipe;
[self.navigationController pushViewController:recipePhotoViewController animated:YES];
[recipePhotoViewController release];
}
}else{
if (self.editing){
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.popover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
[self.popover presentPopoverFromRect:CGRectMake(0, 0, 400, 400) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
self.popover.delegate = self;
[popover release];
}else{
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
recipePhotoViewController.hidesBottomBarWhenPushed = YES;
recipePhotoViewController.recipe = recipe;
[self.navigationController pushViewController:recipePhotoViewController animated:YES];
[recipePhotoViewController release];
}}}
This is working fine and the image is update on, but not during editing.
During editing it shows the image that was there all along, so it can be confusing as anyone using the app can not be sure if the new selected image has been added or updated.
The following is the imagePickerController and the updateButton code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)selectedImage editingInfo:(NSDictionary *)editingInfo {
// Delete any existing image.
NSManagedObject *oldImage = recipe.image;
if (oldImage != nil) {
[recipe.managedObjectContext deleteObject:oldImage];
}
// Create an image object for the new image.
NSManagedObject *image = [NSEntityDescription insertNewObjectForEntityForName:#"Image" inManagedObjectContext:recipe.managedObjectContext];
recipe.image = image;
// Set the image for the image managed object.
[image setValue:selectedImage forKey:#"image"];
// Create a thumbnail version of the image for the recipe object.
CGSize size = selectedImage.size;
CGFloat ratio = 0;
if (size.width > size.height) {
ratio = 44.0 / size.width;
} else {
ratio = 44.0 / size.height;
}
CGRect rect = CGRectMake(0.0, 0.0, ratio * size.width, ratio * size.height);
UIGraphicsBeginImageContext(rect.size);
[selectedImage drawInRect:rect];
recipe.thumbnailImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self dismissModalViewControllerAnimated:YES];}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self dismissViewControllerAnimated:YES completion: nil];
}
Here is the updatePhotoButton:
- (void)updatePhotoButton {
/* How to present the photo button depends on the editing state and whether the recipe has a thumbnail image.
* If the recipe has a thumbnail, set the button's highlighted state to the same as the editing state (it's highlighted if editing).
* If the recipe doesn't have a thumbnail, then: if editing, enable the button and show an image that says "Choose Photo" or similar; if not editing then disable the button and show nothing.
*/
BOOL editing = self.editing;
if (recipe.thumbnailImage != nil) {
photoButton.highlighted = editing;
} else {
photoButton.enabled = editing;
if (editing) {
[photoButton setImage:[UIImage imageNamed:#"choosePhoto.png"] forState:UIControlStateNormal];
} else {
[photoButton setImage:nil forState:UIControlStateNormal];
}
}
}
Does anyone has any idea what would be the problem? I know the UIImagePickerControll has to be used with UIPopoverController in order to work on the iPad, but that is being updated on the -(IBAction)PhotoTapped1 code.
Not sure where to go from here.
Thank you.
Update to question..
PhotoViewController.h
#class Recipe;
#interface RecipePhotoViewController : UIViewController {
#private
Recipe *recipe;
UIImageView *imageView;
}
#property(nonatomic, retain) Recipe *recipe;
#property(nonatomic, retain) UIImageView *imageView;
#end
RecipePhotoViewController.m
#import "RecipePhotoViewController.h"
#import "Recipe.h"
#implementation RecipePhotoViewController
#synthesize recipe;
#synthesize imageView;
- (void)loadView {
self.title = #"Photo";
imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.backgroundColor = [UIColor blackColor];
self.view = imageView;
}
- (void)viewWillAppear:(BOOL)animated {
imageView.image = [recipe.image valueForKey:#"image"];
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)dealloc {
[imageView release];
[recipe release];
[super dealloc];
}
#end
This is an updated data to original question
The reason there's no problem on iPhone is that the previous image isn't visible on iPhone, because you're using a presented view controller: the image picker takes over the entire screen. On iPad, on the other hand, you're using a popover, so the main interface is still visible behind the popover. Thus the user is able to see that the image being tapped is not the image that appears back in the main interface.
But might argue that there's no problem with this. The user hasn't actually accepted the image yet, until the image picker popover is dismissed. You say:
During editing it shows the image that was there all along, so it can be confusing as anyone using the app can not be sure if the new selected image has been added or updated.
But what if the user taps outside the popover to dismiss / cancel it? Surely you wouldn't want the image to have changed in the main interface. The behavior you're objecting to, therefore, is right: you're complaining that the image in the main interface is not updated until the popover is actually dismissed, and that's exactly how it should be. When the user is working in a popover, what's going on behind the popover is irrelevant.

Set Layer Content to UIImage inside a CALayer subclass - not working

I'm trying to display a UIImage selected from a UIImagePickerController inside a subclass of CALayer and add it to my superview but I can't get it to work.
This is how I Get the Image from the UIImagePickerController, which seems to work good :
- (IBAction)importImage:(id)sender
{
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];
[popover setPopoverContentSize:CGSizeMake(320,320)];
[popover presentPopoverFromRect:importBackgroundButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
self.popoverController = popover;
[imagePickerController release];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self.popoverController dismissPopoverAnimated:YES];
UIImage* img = [info objectForKey:UIImagePickerControllerOriginalImage];
[[context currentDrawing] setBkgImage:img];
}
This is my subclass of CALayer which contains the UIImage to display :
#interface UI_BackgroundImageLayer : CALayer
{
//This is for the Import image as background feature
UIImage* _bkgImg;
}
#property (nonatomic, retain) UIImage* _bkgImg;
-(void)update:(UIImage*)src;
#end
////
#implementation UI_BackgroundImageLayer
- (id)init
{
self = [ super init ];
// [self resetTransform ];
_bkgImg = nil;
return self;
}
-(void)update:(UIImage*)src
{
_bkgImg = [[UIImage alloc] initWithCGImage:src.CGImage];
self.contentsGravity = kCAGravityResizeAspect;
self.contents = (id)_bkgImg.CGImage;
}
#end
I update the content of the CALayer when the user select another image !
The CALayer is added to the superview from start like this :
[[_superView layer] insertSublayer:context._imgLayer atIndex:0];
It's inserted at index 0 because it's meant to be a background image so it must be under other UI elements and drawings.
All of this seems good to me, but nothing appears on the screen ...
Are you using XCode v4.2? If so, this may be relevant to you or it may not but it's worth a look. I've had exacty the same problem as you with CALayer subclasses not responding to the usual display methods (like setCornerRadius, setBackgroundColor etc...). Try this; in your hosting view, just after you've instanced the VIEW put the following line;
[self setBackgroundColor [UIColor clearColor]];
You may well find that from that point on, your layer subclass works perfectly.
My view subclass code looks like this;
// layerClass
+ (Class) layerClass {
return [myLayerSubclass class];
}
// View subclass init routine
- (id) initWithFrame: (CGRect) p_frame {
self = [super initWithFrame: p_frame];
if (self) {
[self setBackgroundColor: [UIColor clearColor]]; // *** BUG WORKARUND? *** Note: Do Apple know about this?
// Rest of your view init ....
}
return self;
}
It seems that the layer subclass does not respond until its hosting view has 'acknowledged' that it's there. It took me days to debug but now all my code works perfectly.
Hope this helps.
V.V.

How to implement an image gallery inside an application mimicking the iPhone's default gallery?

I want to implement an image gallery inside my iPhone app which will only have those images from device gallery that have been either selected from inside the app or pictures taken from inside the app. Please advice on any simple methods to do so.
You can try Three20, it's a very nice framework for doing such a task.
Here is some piece of sample code you can use.
In interface :
//IBOutlet UIImageView *image;
UIImagePickerController *imgPicker;
IBOutlet UIImageView *imageview;
Then in viewDidLoad :
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.allowsImageEditing = YES;
//self.imgPicker.delegate = self;
self.imgPicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
//imgarry = [[NSArray alloc]initWithObjects:#"terms.png",#"change-profile.png",nil];
UIImage* img = [UIImage imageNamed:#""];
UIImageWriteToSavedPhotosAlbum(img,nil,nil,nil);
Then in buttonClick :
UIImagePickerController *picker = [[UIImagePickerController alloc]init];
imgPicker.delegate = self;
imgPicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
[self presentModalViewController:imgPicker animated:YES];
[imgPicker release];
This is how i achieve this, don't forget to set #property and #synthesis for image-view and UIImagePicker.
Try Three20 or AQGridView.
You can use UIScrollView with paging=YES.

access camera from uiwebview?

Is it possible to access iphone's camera from uiwebview? I know phonegap does it, but how to make it work without phonegap?
Thanks.
You can implement the UIWebView Delegate and intercept any attempted page load. By setting a custom url, you can pass a message to Objective C, that can launch the camera. To send data back to the web weiw you can initiate a new load (as I do in my example), or pass in some javascript using another method on UIWebView.
Here is a working example, I just wrote:
#import "WebViewCamAppDelegate.h"
#import <UIKit/UIKit.h>
#interface uiwebviewcameraAppDelegate : NSObject <UIApplicationDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIWebViewDelegate> {
UIWindow *window;
UIViewController *viewController;
UIWebView *webView;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
#implementation uiwebviewcameraAppDelegate
#synthesize window;
//This is the HTML we initially show in the WebView. Note the url "showcamera:" is one I
//invented with the intent to intercept it to show the camera.
static NSString *htmlString = #"<br>Show Camera";
//Pretty Basic stuff. We set the UIWebView Delegate so we can intercept the call and set up //a ViewController so we can animate the UIImagePicker
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
viewController = [[UIViewController alloc] init];
webView = [[UIWebView alloc] initWithFrame:window.bounds];
[webView loadHTMLString:htmlString baseURL:nil];
webView.delegate = self;
[viewController.view addSubview:webView];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
//Note: I check to make sure the camera is available. If it is not (iPod touch or Simulator) I show the photo library instead.
-(void) showCamera {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else {
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
imagePicker.delegate = self;
[viewController presentModalViewController:imagePicker animated:YES];
}
//Here we intercept any time the webview tries to load a document. When the user hits our "showcamera: url" we go to work.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[[request URL] scheme] isEqualToString:#"showcamera"]) {
[self showCamera];
return NO;
}
return YES;
}
//After the imagepicker has done it's thing, we pass the data back to the webview to be displayed.
//If we wanted to be fancy here, we could have done this via Javascript so we could dynamically insert an image without reloading the page.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[viewController dismissModalViewControllerAnimated:YES];
UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
NSData *imageData = UIImageJPEGRepresentation (image, 0.5);
[webView loadData:imageData MIMEType:#"image/jpeg" textEncodingName:#"UTF-8" baseURL:nil];
}
- (void)dealloc {
[viewController release];
[webView release];
[window release];
[super dealloc];
}
#end

iPhone SDK - How to display a photo taken with the camera inside a UINavigationController?

This is my code so far:
/* class: myViewController
#interface myViewController: UIViewController
<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
*/
- (IBAction) getPicture {
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
}
- (void) imagePickerController:(UIImagePickerController *)thePicker
didFinishPickingMediaWithInfo:(NSDictionary *)imageInfo
{
[[thePicker parentViewController] dismissModalViewControllerAnimated:YES];
UIImage *img = [imageInfo
objectForKey:#"UIImagePickerControllerOriginalImage"];
self.myImageView.image = img;
}
So basically I'm trying to get a photo from the iPhone camera and display it in a UIImageView. This works perfectly fine as long the class myViewController is displayed as a standalone view. If I'm putting the View inside a UINavigationController the UIImageView won't display the image after taking one with the camera. But if I choose a picture from the library everything is fine again.
So why does the UIImageView won't display a image taken with the camera inside a UINavigationController?
Try to switch the following lines:
[thePicker dismissModalViewControllerAnimated:YES];
UIImage *img = [imageInfo objectForKey:#"UIImagePickerControllerOriginalImage"];
self.myImageView.image = img;
to the following:
UIImage *img = [imageInfo objectForKey:#"UIImagePickerControllerOriginalImage"];
self.myImageView.image = img;
[thePicker dismissModalViewControllerAnimated:YES];
Perhaps the image is released because of the dismissing of the view before you retain it with
self.myImageView.image = img;
Seems to me you're dismissing the wrong viewcontroller. Shouldn't:
[thePicker dismissModalViewControllerAnimated:YES];
read:
[self dismissModalViewControllerAnimated:YES];