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...:)
Related
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.
When i try to load camera from my code, camera preview is black. If I wait for 10-20 seconds it will show real camera preview. I found several questions and some of them suggest that running some other code in background should be the reason for this. However I don't have any code running in background.
How should I fix this?
This is my code where I run camera
UIImagePickerController *photoPicker = [[UIImagePickerController alloc] init];
photoPicker.delegate = self;
photoPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:photoPicker animated:YES completion:NULL];
About 5 months ago my team discovered a memory leak with UIImageViewController in iOS7. Each instantiation slowed down the app exponentially (i.e. first alloc-init had a 1 second delay, second had a 2 second delay, third had a 5 second delay). Eventually, we were having 30-60 delays (similar to what you're experiencing).
We resolved the issue by subclassing UIImagePickerController and making it a Singleton. That way it was only ever initialized once. Now our delay is minimal and we avoid the leak. If subclassing isn't an option, try a class property in your viewController and just lazy load it like so.
-(UIImagePickerController *)imagePicker{
if(!_imagePicker){
_imagePicker = [[UIImagePickerController alloc]init];
_imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
return _imagePicker;
}
Then you can just call it later like:
[self presentViewController:self.imagePicker animated:YES completion:nil];
Had this myself - it happens if something is running on the main dispatch thread - are you resizing images by any chance?
It puts the preview onto the main thread and if something is using it, you get a black screen. It's a bug and the workaround is to either take over the main thread or to disable the photo picker until the queue is free
This Should work for you:
- (void)cameraViewPickerController:(UIImagePickerController *)picker
{
[self startCameraControllerFromViewController: picker
usingDelegate: self];
}
- (BOOL) startCameraControllerFromViewController: (UIViewController*) controller
usingDelegate: (id <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>) delegate {
if (([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera] == NO)
|| (delegate == nil)
|| (controller == nil))
return NO;
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
// Displays a control that allows the user to choose movie capture
cameraUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeImage, (NSString *) kUTTypeMovie,nil];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
cameraUI.allowsEditing = NO;
cameraUI.delegate = delegate;
[controller presentViewController:cameraUI animated:YES completion:nil];
return YES;
}
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 :)
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 !!!
I know this thread existed before, but was closed as only appearing in iOS5 beta 6.
By now I have the Golden Master of iOS 5 on my phone and that error still appears.
This is happening when I create a UIImagePickerController with a sourceType of UIImagePickerControllerSourceTypePhotoLibrary more than 5 times. I am, as far as I can tell, creating and releasing the previous UIImagePickerController correctly each time.
Edit: adding code, as requested.
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.delegate = self;
ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:ipc animated:YES];
[ipc release];
Later, I call [self dismissModalViewControllerAnimated:YES]; when -imagePickerController:didFinishPickingImage:editingInfo: gets called.
The problem happens in Apple examples, so the best bet is to ignore.
Later, I call [self dismissModalViewControllerAnimated:YES]; when
-imagePickerController:didFinishPickingImage:editingInfo: gets called.
Have you tried to set the delegate of the image picker to nil, in didFinishPickingImage ?
This is not your fault.It may be vary in different version.Apple should solve this issue.Main thing is that you should check for memory leak is important.Thanks
Try this UIImagePickerControllerSourceTypePhotoLibrary Error
I hope it will help
try setting
picker=nil
in the
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissModalViewControllerAnimated:YES];
picker = nil;
}
it works for me......
Try this one, i am sure this is gonna help you;
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self setModalInPopover:YES];
}