I need to add objects selected by UIImagePickerController into an NSMutabeArray, the code goes as:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
if(![imagesArray containsObject:[info objectForKey:#"UIImagePickerControllerOriginalImage"]])
{
[imagesArray addObject:[info objectForKey:#"UIImagePickerControllerOriginalImage"]];
}
else {
//some procedures
}
}
The problem is that it always fells into the if block and never executes the else block when picking same images repeatedly. Any clue over this would be appreciated.
I think your problem is that two instances of UIImage can't be compared using isEqual:, which containsObject: is using, even if they point to the same image file. I don't know how to compare two UIImage but you can perhaps look at Generate hash from UIImage or search for "comparing UIImage".
Check by casting. Add it in this way:
UIImage *img =[info objectForKey:#"UIImagePickerControllerOriginalImage"];
if(![imagesArray containsObject:img])
[imagesArray addObject:img];
Related
I am using UIImagePickerViewController to take photo from iPhone default camera in my App and storing it in Document directory. It is taking long time to complete the process and also it is displaying very slowly on tableview.Does resizing image help here?
-(IBAction)takePhoto:(id)sender
{
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])
{
imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:imgPicker animated:YES];
}
}
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *pickedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
[self dismissModalViewControllerAnimated:YES];
NSData *imageData = UIImagePNGRepresentation(pickedImage);
NSString *path = [SAVEDIMAGE_DIR stringByAppendingPathComponent:#"image.png"];
[imageData writeToFile:path atomically:YES];
}
Sure!
I do the following in my app:
store the image in an image store in a background thread
create a thumbnail (also in background thread), store this thumbnail in a core data table; in an field of type ID
So I get a smooth UI, where the User can take about a picture every 2 seconds.
The smoothness of the table views are also no problem. Although I populate the TableViewCells ImageViews also from a background-thread (preparing the image in the background, assigning to the UIImageView in the mainthread, of course).
I hope, that helps you. Further questions are welcome.
Some code for your convenience:
As Imagestore I use these: https://github.com/snowdon/Homepwner/blob/master/Homepwner/ImageStore.m
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self performSelectorInBackground:#selector(saveFoto:) withObject:info];
// you should add some code for indicating the save process
}
// saves the photo in background-thread
-(void)saveFoto:(NSDictionary*)info {
// the following is some stuff that I do in my app - you will probably do some other things
UIImage *image = [ImageHelper normalizeImageRotation: [info objectForKey:UIImagePickerControllerOriginalImage]];
UIImage *thumb = [ImageHelper image:image fitInSize:CGSizeMake(imgWidth, imgWidth) trimmed:YES];
NSString *myGUID = myGUIDCreator();
[[ImageStore defaultImageStore] setImage:image forKey:myGUID];
myCoreDataManagedObject.thumb = thumb;
[self performSelectorOnMainThread:#selector(showYourResultsInTheUI:) withObject:thumb waitUntilDone:NO]; // every UI-Update has to be done in the mainthread!
}
I am trying to save a image by picking it from iphone photo library. But I am not able to save it. My UIImage object suddenly releases. I am getting following error:
* -[UIImage release]: message sent to deallocated instance 0x83fa5b0
Please check my code below:
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(#"finish picking media");
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:#"public.image"]){
UIImage *selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
NSLog(#"found an image");
selectedImage=[self scaleAndRotateImage:selectedImage];
NSLog(#"image scaled");
//add image to mainpic
imgvwProfile.image = selectedImage;
NSLog(#"11");
//[ setImage:selectedImage forState:UIControlStateNormal];
self.imgPic=selectedImage;
//self.isMainPicImageModified=YES;
NSLog(#"22");
//[self sendImage:selectedImage];
NSLog(#"selectedimage width:%f ht:%f",selectedImage.size.width,selectedImage.size.height);
[self saveImage:selectedImage withImageName:#"profilePic.png"];
NSLog(#"33");
}
}
The error appears when NSLog(#"11"); has been execute.
Can some one please help me why I am getting this error?
Thanks
Pankaj
Can you change below line and check whether this statement makes problem or not.
imgvwProfile.image = selectedImage;
To
imgvwProfile.image = [selectedImage retain];
Let me know now your app crash in this function or not.
If the error occurs immediatly after NSLog(#"11") has been executed (you see 11 in the console right?), then it's happening while releasing the former UIImage of self.imgPic. To verify this just put self.imgPic = null; at the beginning of the method.
If so check your code for former release calls on imgPic or other variables pointing to the same UIImage instance. Maybe in scaleAndRotateImage or other methods.
I'm attempting to take and save photos with the camera rapidly, as quickly as the iPhone can. The problem is that they don't save until the end and it then takes forever, or about 1/2 to 3/4 don't save at all (Write busy error or -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL).
I bet I'm just overloading the phone's memory, but I can't think of a way to handle it efficiently. The standard iPhone camera app can handle it just fine -- snap away at almost 1 photo/second and it saves with no problem.
Any ideas on how to manage the process/memory better so that it can save as it goes but still shoot rapidly?
Here's a bit of my code. takePicture is called whenever self.readyToTake = YES.
- (void)takePicture {
self.delegate = self;
[super takePicture];
self.readyToTake = NO;
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
self.readyToTake = YES;
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void)image:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo:(NSDictionary*)info {
if (error)
{
NSLog([NSString stringWithFormat:#"** ERROR SAVING PHOTO: %#", [error localizedDescription]]);
}
}
Thank you for your help!
EDIT
If I resize the photos to much smaller dimensions before saving, like 480x640, I have no problem saving quickly. However, I'm wanting to capture and save full-size images. The native Camera app seems to handle it fine.
you can do like this.
ie., enable taking the next photo only after the previous photo is saved.
Also introduce autorelease pool for memory management.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
[pool drain];
}
- (void)image:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo:(NSDictionary*)info {
if (error)
{
NSLog([NSString stringWithFormat:#"** ERROR SAVING PHOTO: %#", [error localizedDescription]]);
}
self.readyToTake = YES;
}
The first thing I'd try is offloading those calls asynchronously to a dispatch queue:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
self.readyToTake = YES;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
});
}
If you're still having trouble, I'd look into AVCaptureSession and friends. This gives you a lot more control and generally better performance. There's a great sample project using this method at the developer portal: SquareCam
EDIT
You could also try using AssetsLibrary instead of UIImageWriteToSavedPhotosAlbum (This is what we use in all our apps) Something like:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
self.readyToTake = YES;
// you probably want to create this once and keep it around as a property
// on your controller
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
[library writeImageToSavedPhotosAlbum:image.CGImageRef orientation:(ALAssetOrientation)image.orientation completionBlock:^(NSURL *assetURL, NSError *error) {
// do whatever you need to do when the image is saved
}];
}
there is one best example app on developer.apple.com site in which the solution for your problem is shown in it they save photos for 1second interval automatically when user tap on "timed" button here is its code it surely helps you as i can able to store 5 consicutive photos 1/second speed
Please see page MyViewController.m and after getting images in array you can save them to the photo album using some function on another queue
i'm loading photos from my library just fine, but photos coming from he camera don't display in the imageView. I've set allowsImageEditing = YES. I've also used CFShow(info) and the data from the camera is not nil...
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:#"UIImagePickerControllerEditedImage"];
[self.imageView setImage:image];
[self dismissModalViewControllerAnimated:YES];
[picker release];
}
Did you turn on the allowsEditing property of the UIImagePicker? If not, it's not going to return you an editedImage. You'll probably want:
UIImagePickerControllerOriginalImage
I know this is many months later, but I struggled with the same problem and found that though it was asked here many times, it was never answered. Well, I'm happy to say that I figured it out and so am posting it on a few of the nearly-identical questions that come up first on a search.
I posted the full answer here:
didFinishPickingMediaWithInfo return nil photo
i get image from uiimagepickerviewcontroller and set it in global file but when i try to retrieve it from global it will not display in uiimageview
following is code of delegate method form which i get image
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
UIImage *tempimg = image;
[Global setimage:tempimg];
isphototeken = TRUE;
[picker dismissModalViewControllerAnimated:NO];
[tblsubmenu reloadData];
NSLog(#"global image %#",[Global getimage]);
[picker release];
}
error at display time
bad exception application is terminate
I think the problem is with this line.
NSLog(#"global image %#",[Global getimage]);
giving image to the log???
you just try to comment out this line and run and check whether the application runs or not