Saving and Retrieving Image Makes App Slow - iphone

I save picture from UIImagePicker this way:
Save picture in file and then I save path to the fail in NSUserDefaults and then in another class I retrieve the picture by this saved path.
Code:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
ideaImage.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[picker dismissModalViewControllerAnimated:YES];
}
-(void)saveIdea_alt
{
[self performSelector: #selector(saveIdea) withObject:nil afterDelay:0.1];
}
-(void)saveIdea
{
UIImage *ideaPhoto = ideaImage.image;
NSData *imageData = UIImagePNGRepresentation(ideaPhoto);
NSString* imageName = #"MyImage.png";
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:imageName];
[imageData writeToFile:fullPathToFile atomically:NO];
NSArray *arrayKeys = [[NSArray alloc]initWithObjects:#"ideaName",#"ideaCost",#"ideaNote", #"ideaImage", nil];
NSArray *arrayObjects = [[NSArray alloc]initWithObjects:ideaName.text,ideaCost.text,ideaNote.text,fullPathToFile , nil];
NSDictionary *dictionary = [[NSDictionary alloc]initWithObjects:arrayObjects forKeys:arrayKeys];
NSMutableArray *ideasArray = [[NSMutableArray alloc]initWithArray:[[NSUserDefaults standardUserDefaults]objectForKey:#"ideasArray"]];
[ideasArray addObject:dictionary];
[[NSUserDefaults standardUserDefaults]setObject:ideasArray forKey:#"ideasArray"];
[self dismissModalViewControllerAnimated:YES];
}
However, after that my app becomes slow and it saves and loads images slowly. What I do wrong ?
Thanks !

One interesting optimization to look at is not saving it into NSUserDefaults, and using Core Data.
There are a lot of reasons for this, but one important one is that when you want to add and remove things from NSUserDefaults, the app has to load all of NSUserDefaults into memory just go retrieve one key.

Related

Saving and Retrieving Image Makes App Working Slowly

I save picture from UIImagePicker this way:
Save picture in file and then I save path to the fail in NSUserDefaults and then in another class I retrieve the picture by this saved path.
Code:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
ideaImage.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[picker dismissModalViewControllerAnimated:YES];
}
-(void)saveIdea_alt
{
[self performSelector: #selector(saveIdea) withObject:nil afterDelay:0.1];
}
-(void)saveIdea
{
UIImage *ideaPhoto = ideaImage.image;
NSData *imageData = UIImagePNGRepresentation(ideaPhoto);
NSString* imageName = #"MyImage.png";
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:imageName];
[imageData writeToFile:fullPathToFile atomically:NO];
NSArray *arrayKeys = [[NSArray alloc]initWithObjects:#"ideaName",#"ideaCost",#"ideaNote", #"ideaImage", nil];
NSArray *arrayObjects = [[NSArray alloc]initWithObjects:ideaName.text,ideaCost.text,ideaNote.text,fullPathToFile , nil];
NSDictionary *dictionary = [[NSDictionary alloc]initWithObjects:arrayObjects forKeys:arrayKeys];
NSMutableArray *ideasArray = [[NSMutableArray alloc]initWithArray:[[NSUserDefaults standardUserDefaults]objectForKey:#"ideasArray"]];
[ideasArray addObject:dictionary];
[[NSUserDefaults standardUserDefaults]setObject:ideasArray forKey:#"ideasArray"];
[self dismissModalViewControllerAnimated:YES];
}
However, after that my app becomes slow and it saves and loads images slowly. What I do wrong ?
I don't really want to use Core Data because I already save all others properties of idea in NSUserDefaults (like cost, name, color and etc.)
After setting values in NSUserDefaults,Just write this line :
[[NSUserDefaults standardUserDefaults] synchronize];
Hope this will help.
Have you tried using
[self performSelectorInBackground: #selector(saveIdea) withObject:nil];
instead of
[self performSelector: #selector(saveIdea) withObject:nil afterDelay:0.1];

UIImagePickerController - Save and Retrieve photo from Apps Document Directory

This is driving me crazy!
I'm successfully saving a photo to my applications document directory from both the camera and if I choose an existing one from the camera roll. The code to do this is as follows. Note I know this part is working because in the simulator I can browse to the apps Documents folder and see the file being saved.
Example "save" code:
//Note: code above snipped to keep this part of the question short
case 1:
{
// select from library
NSLog(#"select from camera roll");
if([util_ isPhotoLibraryAvailable])
{
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
controller.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
NSMutableArray *mediaTypes = [[NSMutableArray alloc] init];
if([util_ canUserPickPhotosFromPhotoLibrary])
{
[mediaTypes addObject:(__bridge NSString *)kUTTypeImage];
}
controller.mediaTypes = mediaTypes;
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
}
} break;
//code below snipped out
And once the image is taken or selected:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSLog(#"picker returned successfully");
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if([mediaType isEqualToString:(__bridge NSString *)kUTTypeImage])
{
UIImage *originalImage = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImage *resizedImage = [util_ createThumbnailForImage:originalImage thumbnailSize:[util_ determineIPhoneScreenSize]];
NSData *imageData = UIImagePNGRepresentation(resizedImage);
NSString* imageName = #"MyImage.png";
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:imageName];
[imageData writeToFile:fullPathToFile atomically:NO];
NSLog(#"fullPathToFile %#", fullPathToFile);
// this outputs the following path in the debugger
// fullPathToFile /Users/me/Library/Application Support/iPhone Simulator/5.0/Applications/47B01A4C-C54F-45C4-91A3-C4D7FF9F95CA/Documents/MyImage.png
// rest snipped out - at this point I see the image in the simulators/app/Documents directory
Now - the part that is NOT working (fetching and displaying the photo):
// code above snipped out (we're in tableView:cellForRowAtIndexPath)
imageButton_ = [[UIButton alloc] initWithFrame:CGRectMake(5, 5, 200, 200)];
NSString* imageName = [contentArray_ objectAtIndex:indexPath.row];
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
SString* documentsDirectory = [paths objectAtIndex:0];
NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:imageName];
UIImage *image = [UIImage imageNamed:fullPathToFile];
[imageButton_ setImage:image forState:UIControlStateNormal];
[cell addSubview:imageButton_];
NSLog(#"fullPathToFile: %#", fullPathToFile);
// this outputs the following path in the debugger
// fullPathToFile: /Users/me/Library/Application Support/iPhone Simulator/5.0/Applications/47B01A4C-C54F-45C4-91A3-C4D7FF9F95CA/Documents/MyImage.png
return cell;
}
So, I get an empty button with no image displayed in the cell. I have also substituted the button for a UIImageView and still no luck...
Your problem is here:
UIImage *image = [UIImage imageNamed:fullPathToFile];
UIImage imageNamed: is only for images in the bundle. It doesn't work for images in the documents directory.
Try imageWithContentsOfFile: instead.

How to Display photos from NSDocumentDirectory

I'm developing this application on an iPad.
These codes for a 'Browse' button allows the user to view the photos from the iPad's gallery.
Code:
- (IBAction) BrowsePhoto:(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:CGRectMake(200,200,-100,-100) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
self.popoverController = popover;
[imagePickerController release];
}
When a photo is selected, it will be stored into the application using NSDocumentDirectory.
Code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)selectedImage editingInfo:(NSDictionary *)editingInfo
{
[self.popoverController dismissPopoverAnimated:YES];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:#"SavedImage.png"];
UIImage *image = imageView.image;
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:NO];
}
Now i have to include a 'Display' button on the first screen.
When tapped on the button, it will show a new view (modal view controller) and displays all the photos in thumbnails/tableview from the NSDocumentDirectory.
When a photo is selected, it will be deleted from the NSDocumentDirectory.
How can i do this?
To Delete any file in NSDocumentDirectory in iPhone, U can use this code,
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES );
NSString *docDirectory = [sysPaths objectAtIndex:0];
NSString *filePath2 = [NSString stringWithFormat:#"%#/%#", docDirectory,#"SavedImage.png"];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL exist =[fileManager fileExistsAtPath:filePath2];
if(exist)
[fileManager removeItemAtPath:filePath2 error:NULL];

Find Photo in Directory! (Programmatically)

Holy Dudes from stackoverflow,
MY PROBLEM: I need to send an email with 3 attachments. The first that is the .txt, is going well, no problems with him, but the problem is with the pictures. I capture a printscreen with this:
-(IBAction)screenShot{
maintimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(update) userInfo:nil repeats:YES];
}
-(void)update{
time = time + 1;
if(time == 2){
[self hideThem]; //hides the buttons
UIGraphicsBeginImageContext(self.bounds.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(screenImage, nil, nil, nil);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"GRAPH SAVED" message:#"YOUR GRAPH HAS BEEN SAVEN IN THE PHOTO ALBUM" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
[maintimer invalidate];
time = 0;
}
[self bringThem]; //brings the buttons back
}
But now i need to get this image i created! I tried using the same code i use for the text:
-(IBAction)sendMail
{
(..)
//HERE IS WHERE THE NAME IS GIVEN
NSString *filename = [NSString stringWithFormat:#"%f.txt", [[NSDate date] timeIntervalSince1970]];
//THIS IS GOING TO STORE MY MESSAGE STUFF
NSString *content = [[NSMutableString alloc]init];
(...) //LOTS OF UNNECESSARY CODE
//HERE IS WHERE IT BILDS THE FILE
[self writeToTextFile:filename content:content];
//HERE IS THE CODE WHERE IT ATTACHES THE FILE
[self sendMailWithFile:filename];
//[content release];
}
-(void)sendMailWithFile : (NSString *)file
{
//THIS IS THE CODE THAT GETS THE TEXT
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = [NSString stringWithFormat:#"%#/%#", documentsDirectory, file];
NSData *data = [[NSData alloc] initWithContentsOfFile:fileName];
//THIS WAS MY TRY TO GET THE PHOTO ON THE SAME STYLE OF THE TEXT
NSArray *photoPath = NSSearchPathForDirectoriesInDomains(NSPicturesDirectory, NSUserDomainMask, YES);
NSString *photoDirectoryForFirstPhoto = [photoPath objectAtIndex:0];
NSString *photoName_First = [NSString stringWithFormat:#"%#/%#", photoDirectoryForFirstPhoto, /*I DO NOT HAVE THE PHOTO NAME*/#"FirstPhoto"];
NSData *photoData_First = [[NSData alloc] initWithContentsOfFile:photoName_First];
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
if ([MFMailComposeViewController canSendMail])
{
mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setSubject:#"RK4 data"];
[mailComposer addAttachmentData:data mimeType:#"text/plain" fileName:#"[RK4][EQUATION][TEXT]"];
[mailComposer addAttachmentData:photoData_First mimeType:#"image/png" fileName:#"[RK4][EQUATION][IMAGE]"];
[mailComposer setMessageBody:#"iCalculus Runge-Kutta data." isHTML:NO];
[self presentModalViewController:mailComposer animated:YES];
}
else (...)
[mailComposer release];
[data release];
}
So that's my problem. I need to find a way to get the printscreen i took and attach it.
Because i need to come up with all the attaches in the email as soon as he clicks the "SEND MAIL" button.
Thanks.
Rather than saving to your photo library, you should save to documents directory, or tmp directory, to get documents directory you can use the following.
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* dd = [paths objectAtIndex:0];
NSString *path = [dd stringByAppendingPathComponent:#"file.png"];
[UIImagePNGRepresentation(screenImage) writeToFile:path atomically:NO];
Take a look here for how to embed the image directly inside the email using base-64, that should be much cleaner than dumping temporary images to the users saved photos album.
Edit:
Category for handling base 64 with NSData, use the download towards the bottom.

Trying to save images in ipad app bundle from photo library

-(IBAction)saveImage{
NSMutableArray *dictWords= [[NSMutableArray alloc]initWithObjects:#"TIGER",#"CAT", #"ROSE", #"ELEPHANT",#"MOUSE IS LOOKING FOR THE CHEESE",#"KITE",#"CAR",#"AEROPLANE",#"MANGO",#"FRUITS ARE FALLING FROM THE TREE",#"MOUNTAIN",#"BIRDS ARE FLYING",#"IGLOO",#"THIS HOUSE IS BUILT OF WOODS",#"BANANA",#"RAINBOW",#"TRAIN",#"DADDY DRINKS JUICE",#"UMBRELLA",#"GOAT",#"CAT JUMPS HIGH",#"DOG RUNS FAST",#"BUS",#"GIRL IS CRYING",#"STARS",#"DOLPHIN",#"BOYS ARE PLAYING FOOTBALL",#"GLASS IS FULL OF WATER",#"SHIP",#"SNOWFALL",#"GHOST",#"RABBIT",#"WATERMELON",#"SPIDERMAN",#"DINOSAUR",#"MICKEY MOUSE",#"MONKEY IS SITTING ON A TREE",#"PEACOCK",#"LIGHTNING",#"HEN LAYS EGGS",nil];
NSString *path=[[NSBundle mainBundle] pathForResource:[youSaid text] ofType:#"png" inDirectory:#"Image"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for (int i=0 ; i<[assets count]; i++) {
if (i<[dictWords count]) {
[dict setObject:[[[assets objectAtIndex:i] defaultRepresentation] url] forKey:[NSString stringWithFormat:#"%#",[dictWords objectAtIndex:i]]];
NSLog(#"diccount:%d",[dict count]);
}
}
NSURL *imageurl = [dict objectForKey:[youSaid text]];
//NSLog(#"text:%#",[youSaid text]);
//Getting asset from url
typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
//Setting asset image to image view according to the image url
[imageview setImage:[UIImage imageWithCGImage:iref]];
youSaid.text = [NSString stringWithFormat:#"%#",imageurl];
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(#"Error, cant get image - %#",[myerror localizedDescription]);
};
ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
[assetLibrary assetForURL:imageurl resultBlock:resultblock failureBlock:failureblock];
UIImage *image=[[UIImage alloc]initWithContentsOfFile:path];
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", youSaid.text]]; //add our image to the path
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the image
NSLog(#"image saved");
}
#end
This is the following code i wrote but i am not able to save images.i am only able to sane an image known as NULL.png .please suggest the changes to save all the pics in my library to bundle.
Thanks,
Christy
Sample Code
- (void) openPhotoLibrary {
NSLog(#"openPhotolibrary");
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
if (self.picker != nil) {
NSLog(#"releasing self.picker...");
[self.picker release];
}
self.picker = [[UIImagePickerController alloc] init];
self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
//self.picker.allowsImageEditing = YES;
[self.picker presentModalViewController:self.picker animated:YES];
self.picker.delegate = self;
[[[CCDirector sharedDirector] openGLView] addSubview:self.picker.view];
}
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)currentPicker {
NSLog(#"imagePickerControllerDidCancel");
// hide the self.picker if user cancels picking an image.
[currentPicker dismissModalViewControllerAnimated:YES];
self.picker.view.hidden = YES;
[self.picker.view removeFromSuperview];
}
- (void)imagePickerController:(UIImagePickerController *)currentPicker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
[self saveImage:image withImageName:#"myPhoto"];
}
//saving an image
- (void)saveImage:(UIImage*)image withImageName:(NSString*)imageName {
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", imageName]]; //add our image to the path
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the path (image)
NSLog(#"image saved");
}
This code its working for me try it may be its helps you
-(IBAction)PhotoLibraryButtonClicked:(id)sender{
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imagePicker animated:YES];
}
else{
[self displaysorceError];
}
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
//[self.popoverrcontroller dismissPopoverAnimated:true];
//[popoverrcontroller release];
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
[self dismissModalViewControllerAnimated:YES];
if([mediaType isEqualToString:(NSString *)kUTTypeImage]){
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// UIImage *rote = [image rotateInDegrees:219.0f];
img.image = image;
if(newMedia)
UIImageWriteToSavedPhotosAlbum(image, nil,nil, nil);
}else if([mediaType isEqualToString:(NSString *)kUTTypeImage]){
//not available vidio
}
}
-(IBAction)saveImageIn:(id)sender{
NSData *imageData = UIImagePNGRepresentation(img.image);
NSFileManager *fileMan = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPathToFile = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#" %d.png",img.image]];
[fileMan createFileAtPath:fullPathToFile contents:imageData attributes:nil];
UIAlertView *alt = [[UIAlertView alloc]
initWithTitle:#"Thank You"
message:#"Image Save In Directory"
delegate:nil cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alt show];
[alt release];
}
thank you..:)Neet