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.
Related
I'm using ELCImagePickerController in my project. Select multiple images from the gallery through it. I'm facing an issue that , how i can show the selected multiple images in an image view in a view controller. I have created a select image button which take us to photolibrary where we select multiple images.My code is,
- (IBAction)Select:(id)sender {
ELCImagePickerController *elcPicker = [[ELCImagePickerController alloc] initImagePicker];
elcPicker.maximumImagesCount = 100; //Set the maximum number of images to select to 100
elcPicker.returnsOriginalImage = YES; //Only return the fullScreenImage, not the fullResolutionImage
elcPicker.returnsImage = YES; //Return UIimage if YES. If NO, only return asset location information
elcPicker.onOrder = YES; //For multiple image selection, display and return order of selected images
// elcPicker.mediaTypes = #[(NSString *)kUTTypeImage, (NSString
*)kUTTypeMovie]; //Supports image and movie types
elcPicker.imagePickerDelegate = self;
[self presentViewController:elcPicker animated:YES completion:nil];
}
- (void)elcImagePickerController:(ELCImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSArray *)info
{
[self dismissViewControllerAnimated:YES completion:nil];
for (NSDictionary *dict in info)
{
if ([dict objectForKey:UIImagePickerControllerMediaType] ==
ALAssetTypePhoto)
{
if ([dict objectForKey:UIImagePickerControllerOriginalImage])
{
UIImage* image=[dict
objectForKey:UIImagePickerControllerOriginalImage];
_arrimage.image;
}
}
}
}
- (void)elcImagePickerControllerDidCancel:(ELCImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:nil];
}
You can use CreolePhotoSelection to get and select multiple images. It will help to you gets multiple selection and retrieve all selected value into delegate method.
Below is the sample code for it:
CreolePhotoSelection *objCreolePhotoSelection= [[CreolePhotoSelection alloc] initWithNibName:#"CreolePhotoSelection" bundle:nil];
objCreolePhotoSelection.strTitle = YOUR_TITLE_FOR_PHOTO_VIEW;
objCreolePhotoSelection.delegate = self; // It will help to retrive all selected photos from CreolePhotoSelection
objCreolePhotoSelection.arySelectedPhoto = YOUR_CURRENT_ARRAY; // You need to pass same array which is holding selected image
objCreolePhotoSelection.maxCount = YOUR_MAX_PHOTOS_LIMIT; // Eg. 5, 10 anythings...
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:objCreolePhotoSelection];
[self.navigationController presentViewController:navController animated:YES completion:nil];
// Delegate Method
#pragma mark - Photo selected Delegate Method
-(void)getSelectedPhoto:(NSMutableArray *)aryPhoto
{
// You will selected image array into aryPhoto object and you can use it
}
First of all an Image View is to show a single image. From the piece of code you shared I am not clear what did you mean by
UIImage* image=[dict
objectForKey:UIImagePickerControllerOriginalImage];
_arrimage.image;
What does this _arrimage mean? Is that a reference to the Image view? then it should be
_arrimage.image = image; //the image fetched in the above line
But this won't fix your issue as this will show only the very last object found in the for loop (probably the last selected image).
To show all selected images it is better to go with a collection view with the array of images as the data source and load each images in each cells of the collection view.
If you want to show all images within the same image view, there is another option by setting it as animationimages
imageView.animationImages = imagesListArray //the list of image you selected
imageView.animationDuration = 2.0
imageView.startAnimating()
This just show each images one at a time from the array with a time interval of 2 seconds
You can't Show Multiple Images in a single ImageView at a same time but yes you can show multiple images on a same ImageView for sometime using Image Animation.
var imagesArray = [UIImage]()
for imageName in 1...3
{
imagesArray.append(UIImage(named: "\(imageName).png")!)
}
// You can also use below code to add images if not want to use loop
// imagesArray.append(UIImage(named: "a.png")!)
// imagesArray.append(UIImage(named: "b.png")!)
// imagesArray.append(UIImage(named: "c.png")!)
self.imageView.animationImages = imagesArray
self.imageView.animationDuration = 2.0
self.imageView.startAnimating()
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...:)
I am getting a memory warning and the app crashes.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
[self.btnSelectImage setImage:image forState:UIControlStateNormal];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
[popOverSelectImage2 dismissPopoverAnimated:YES];
UIViewController *vc = [[UIViewController alloc]init];
vc.view = self.captionView;
[popOverSelectImage setPopoverContentSize:CGSizeMake(self.captionView.frame.size.width, self.captionView.frame.size.height) animated:NO];
popOverSelectImage.contentViewController = vc;
[vc release];
}
else
{
[self dismissModalViewControllerAnimated:YES];
}
self.imageToSave = image;
self.imagePicker = nil;
}
When you set an image on a button, although it is displayed at a smaller size, it is using the full image, which, if you are getting it from the camera library, is going to be reasonably big.
If you are using a lot of these images, then you are going to be using a lot of memory.
If you want to use lots of these images as button images, then you should create smaller images at the size you require and use these thumbnails instead of the full image. You'll use a lot less memory this way.
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 !!!
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.