Memory warning when using UIImagePickerController - ios

Im getting a memory warning when Im using the camera on an iPhone. Im also using ARC.
When you take a photo and press the 'use Photo' button on the camera view controller I get a memory warning. The intention is once the 'use Photo' button is pressed that it changes the contents of the an ImageView.
I thought the memory issue might be due to the fact that the image that is captured is full screen, and the ImageView is 250h 250w. But I tried scaling down the size of the image taken by the camera and then assign it to the ImageView. However this still did not work, even when I resized it to 100 x 100.
Secondly, I then did not assign the photo taken by the camera to the ImageView but it still has the memory warning.
I looked at other answers here and attempted the two above but it is still there. I will show my code below. Will this affect my submission to the app store? Surely if it is such a common occurence that it is a bug or there is a work around? It would be great if one could look at the code provided and spot the error or suggest how to handle this memory warning?
My app is 95+% finished apart from this memory warning so it is getting close to submission time.
My code:
- (IBAction)takePhoto:(id)sender {
self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.delegate = self;
self.imagePicker.allowsEditing=NO;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
[self.imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[self presentViewController:self.imagePicker animated:YES completion:NULL];
}
else{
[self.imagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:self.imagePicker animated:YES completion:NULL];
}
}
- (IBAction)choosePhoto:(id)sender {
self.imagePicker2 = [[UIImagePickerController alloc] init];
self.imagePicker2.delegate = self;
self.imagePicker2.allowsEditing=NO;
[self.imagePicker2 setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:self.imagePicker2 animated:YES completion:NULL];
}
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
CGRect rect = CGRectMake(0,0,100,100);
UIGraphicsBeginImageContext( rect.size );
[self.image drawInRect:rect];
UIImage *picture1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.snapImage setImage:picture1];
[self.uploadImageBtn setHidden:NO];
[self dismissViewControllerAnimated:YES completion:NULL];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[self dismissViewControllerAnimated:YES completion:NULL];
}

I didnt find a good solution but I would not store the raw image in a property because the raw image takes up roughly 30MB of memory. So instead of:
self.image = [info objectForKey:UIImagePickerControllerOriginalImage];
I changed it to:
UIImage * image = [info objectForKey:UIImagePickerControllerOriginalImage];
This way the image is destroyed when it is no longer in use. Note: I've test this new method on iPhone 4 series and 5. The memory warning only appears on the 4 series not the 5.
From looking around the web there have been many bug reports submitted to Apple in regards to the Camera and iOS7. For instance, irregularly when you launch the Camera it will give a black preview - this is linked to iOS7, and more so the iPhone 4 series not 5. This is probably the difference in the processor power - but I am not sure. My app got approved for the app store so the memory warning will not be an issue –

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
Clearing the Cache in the class i was using the "UIImagePickerController", worked for me !!!

Related

IOS 10 UIImagePickerController Delegate Not Being Called

I have setup the following to select an image whilst using an IPad. The problem is that the delegate never seems to get called. I've placed breakpoints in but they are never activated.
.H
#interface HomeViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
.M
- (IBAction)loadImage:(id)sender {
self.imagePickerController = [[UIImagePickerController alloc] init];
self.imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
self.imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.imagePickerController.allowsEditing = NO;
self.imagePickerController.delegate = self;
[self presentViewController:self.imagePickerController animated:YES completion:nil];
}
// This method is called when an image has been chosen from the library or taken from the camera.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//You can retrieve the actual UIImage
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
//Or you can get the image url from AssetsLibrary
NSURL *path = [info valueForKey:UIImagePickerControllerReferenceURL];
[picker dismissViewControllerAnimated:YES completion:nil];
}
Can anyone see the issue?
Thanks
if you used Xcode8 to run the project, please check the project's info.plist, make sure there is a key for "Privacy Photo library usage".
your code is right, maybe the problem is the info.plist.
I had a similar issue and it turned out that the picker was being garbage collected as soon as the image was picked, so the delegate wasn't called.
I needed to ensure that a strong reference to the picker was made before presenting it.
Once that was done, it worked fine.

UIImagePickerControllerOriginalImage received memory warning and getting crash

I have a UICollectionView and a bar button at top right(CameraViewController1 : UICollectionViewController).The flow is when I take a picture it moves to a new view controller where the image can be cropped.User has two option Use and Cancel after choosing any of this option it gets back the image to the collection view and it gets arranged like cells.I want to take many photos.But I can take up to 3 pictures only where as the app crashes immediately and shows a message "App terminated due to memory pressure".But the worst part is when I tested the same app in iPhone 5 running iOS 7 the crash wasn't happen.When I test the same in iPhone 4 running iOS 7 it gets crashed and produce received memory warning.
Here my code
- (IBAction)TakeaPhoto:(id)sender {
[[UIApplication sharedApplication]setStatusBarHidden:FALSE withAnimation:NO];
gallery=0;
picker1 = [[UIImagePickerController alloc] init];
picker1.delegate = self;
self.resizeableCropArea =YES;
self.cropSize=CGSizeMake(300,350);
//picker1.allowsEditing = YES;
picker1.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker1 animated:YES completion:NULL];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismissViewControllerAnimated:YES completion:NULL];
UIImage *image = [info objectForKey: UIImagePickerControllerOriginalImage];
image_cap = [self imageTemp:image scaledToSize:CGSizeMake(320, 370)];
dataTemp = UIImageJPEGRepresentation(image,0.0);
CropViewController *cropController = [[CropViewController alloc] init];
cropController.sourceImage = [info objectForKey:UIImagePickerControllerOriginalImage];
Original_img = UIImageJPEGRepresentation(cropController.sourceImage,0.0);
[original_image addObject:[UIImage imageWithData:Original_img]]; //original_image Nsmutablearray
NSLog(#"source image=%#",cropController.sourceImage);
cropController.resizeableCropArea = self.resizeableCropArea;
cropController.cropSize = self.cropSize;
cropController.delegate = self;
Cancel_Image= cropController.sourceImage;
[self.navigationController pushViewController:cropController animated:YES];
}
#Ramanan R R, I m totally agree with the #Rushabh's comment..
You are allocating that UIImagePickerController for many more times, as TakeaPhoto method call you are allocating UIImagePickerConrtoller, it is not necessary to allocate that multiple times. It makes memory spoilage, thats why your app is going to terminate or crash..
Just allocate that one time in viewDidLoad, make sure one more thing that, do
UIImagePickerController as a strong property, because in past it took my whole day to solve issue...
Hope this will work for you and your app will run smoothly...:)

uiimagepickercontrolleroriginalimage memory waring

I have a collection view (UICollectionViewController subclass) where I placed a UIBarButtonItem named "Take a photo". When I tap the bar button item my camera opens & I take a photo. In my project after "Use Photo" from camera it will move to a crop view controller where I crop the image after selecting the image from my crop view the image gets placed here in my collection view the current controller. In crop view I have two buttons use and cancel.My problem is when I take oddly 2,3 or 4 I receive a memory warning in console then the app crashes with a alert "application terminated due to memory pressure". I've been using this code, when I use UIImagePickerControllerEditedImage there is no issue instead if I use UIImagePickerControllerOriginalImage I come across memory issue.
My problem is to provide a good quality image and this UIImagePickerControllerOriginalImage provides a good quality than UIImagePickerControllerEditedImage.I have to get rid of this memory issue and so I used this line [self dismissViewControllerAnimated:YES completion:NULL];but I couldn't able clear the memory warning.
- (IBAction)TakeaPhoto:(id)sender {
[[UIApplication sharedApplication]setStatusBarHidden:FALSE withAnimation:NO];
gallery=0;
picker1 = [[UIImagePickerController alloc] init];
picker1.delegate = self;
self.resizeableCropArea =YES;
self.cropSize=CGSizeMake(296, 350);
picker1.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker1 animated:YES completion:NULL];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info objectForKey:
UIImagePickerControllerOriginalImage];
image_cap = [self imageTemp:image scaledToSize:CGSizeMake(320, 370)];
dataTemp = UIImageJPEGRepresentation(image,0.0);
CropViewController *cropController = [[CropViewController alloc] init];
cropController.sourceImage = [info objectForKey:UIImagePickerControllerOriginalImage];
Original_img = UIImageJPEGRepresentation(cropController.sourceImage,0.0);
[original_image addObject:[UIImage imageWithData:Original_img]];
NSLog(#"source image=%#",cropController.sourceImage);
cropController.resizeableCropArea = self.resizeableCropArea;
cropController.cropSize = self.cropSize;
cropController.delegate = self;
Cancel_Image= cropController.sourceImage;
[self dismissViewControllerAnimated:YES completion:NULL];
[self.navigationController
pushViewController:cropController animated:YES];
}
Maybe you should compress your JPEG images. For example if you need that your images have a size less than 70kb, you can use this code:
float compressionRate = 0.90; // Initial compression rate
float maxCompressionRate = 0.10; // Max compression rate
NSData *data = UIImageJPEGRepresentation(outputImage, compressionRate);
// Our limit of size is MAX_UPLOAD_SIZE (70000) and compressionRate is 0.03f
while ([data length] > MAX_UPLOAD_SIZE && compressionRate >= maxCompressionRate) {
compressionRate -= 0.03;
data = UIImageJPEGRepresentation(outputImage, compressionRate);
}
Note: you can edit MAX_UPLOAD_SIZE with you desired size in bytes.

App using a map (apple or google) often killed due to memory pressure (Mainly happens when going to Camera)

Description
my app is only using 35-70mb and is sometimes getting killed with 35mb in the report. The reason always being vm-pageshortage
go from any map view to the camera (repeat N times. on devices with a lot of free RAM it takes longer of course)
you will start (quite soon(!) to receive memory warnings
BOOM (killed)
This works in any app that uses either MKMapKit or GoogleMaps. I guess it is related some graphics data that doesnt show up in instruments but is in the VM.
This didnt happen in IOS6
GMS Bug Tracker issue with DEMO code
https://code.google.com/p/gmaps-api-issues/issues/detail?id=6209&thanks=6209&ts=1388925382)
question 1
Im releasing the objects just fine on my side and I see dealloc is called correctly.
=> can I somehow influence MapKit / GoogleMaps to release VM space.
question 2
What's strange is that according to the report there are even bigger apps on the system but ours gets killed:
=> Is there some mechanic in the whatchdog to prefer to kill DEBUG (or maybe non-appstore) apps before appstore apps?
Sample project:
only 1 view controller, only 1 map (via Apple MapKit, GMS is equally bad), push camera and take a pic--- BOOM
runnable code: https://dl.dropboxusercontent.com/u/3753090/MapKitTest.zip
- (void)loadView {
UIView *v = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
CGRect f = v.bounds;
mapView = [[MKMapView alloc] initWithFrame:CGRectInset(f, 5, 5)];
[v addSubview:mapView];
self.view = v;
}
- (void)viewDidAppear:(BOOL)animated {
[self performSelector:#selector(delayed) withObject:nil afterDelay:3];
}
- (void)delayed {
UIImagePickerController* imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.delegate = (id)self;
imagePickerController.showsCameraControls = NO;
[self presentViewController:imagePickerController animated:YES completion:nil];
[imagePickerController performSelector:#selector(takePicture) withObject:nil afterDelay:2];
}
- (void)imagePickerController:(UIImagePickerController *)imagePicker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
NSData *jpg = UIImageJPEGRepresentation(image, 0.8);
NSLog(#"jpg %d", ((const char*)jpg.bytes)[0]);
[self dismissViewControllerAnimated:YES completion:nil];
}
an instruments screenshot:
https://www.dropbox.com/s/v1v5ll8v5kjt7ev/Screenshot%202014-01-05%2021.00.58.png
and the report:
https://dl.dropboxusercontent.com/u/3753090/report%2005-01-14%2021-00.crash
apple acknowledged the bug and claims to have fixed it with 7.1 -- anyhow they confirmed the issue so there is no mistake on my side.
I guess a 4s is just no device for ios7 anymore :)

Capture image with out saving on Device using UIImagePickerController

Hi is it possible to capture an Image with out saving to ios device .This is a question that is worrying me.
Can any please give me an idea how to achieve it.
Yes it is possible:
- (void)takePhoto
{
UIImagePickerController * pc = [[UIImagePickerController alloc] init];
pc.sourceType = UIImagePickerControllerSourceTypeCamera;
pc.delegate = self;
pc.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
pc.allowsEditing = YES;
[self presentViewController:pc animated:YES completion:^{
}];
}
#pragma mark - UIImagePickerController Delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:^{
UIImage * image = [info valueForKey:#"UIImagePickerControllerOriginalImage"];
self.imageView.image = image;
}];
}
Edit:
If you want to save the image you can simply save it to the Caches directory (see the apple docs for NSFileManager for info on how to do this, or other stack overflow questions. This is preferred to NSUserDefaults although that would work too.
If you want to simply send it (via email, share, or API upload) you dont have to save it first. You can use the in-memory version that resides in the self.imageView.image property above.

Resources