UIImagePickerController Save to Disk then Load to UIImageView - iphone

I have a UIImagePickerController that saves the image to disk as a png. When I try to load the PNG and set a UIImageView's imageView.image to the file, it is not displaying.
Here is my code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
NSData *imageData = UIImagePNGRepresentation(image);
// Create a file name for the image
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
NSString *imageName = [NSString stringWithFormat:#"photo-%#.png",
[dateFormatter stringFromDate:[NSDate date]]];
[dateFormatter release];
// Find the path to the documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// Now we get the full path to the file
NSString *fullPathToFile = [documentsDirectory stringByAppendingPathComponent:imageName];
// Write out the data.
[imageData writeToFile:fullPathToFile atomically:NO];
// Set the managedObject's imageLocation attribute and save the managed object context
[self.managedObject setValue:fullPathToFile forKey:#"imageLocation"];
NSError *error = nil;
[[self.managedObject managedObjectContext] save:&error];
[self dismissModalViewControllerAnimated:YES];
}
Then here is how I try to load it:
self.imageView.backgroundColor = [UIColor lightGrayColor];
self.imageView.frame = CGRectMake(10, 10, 72, 72);
if ([self.managedObject valueForKey:#"imageLocation"] != nil) {
NSLog(#"Trying to load the imageView with: %#", [self.managedObject valueForKey:#"imageLocation"]);
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[self.managedObject valueForKey:#"imageLocation"]];
self.imageView.image = image;
} else {
self.imageView.image = [UIImage imageNamed:#"no_picture_taken.png"];
}
I get the message that it's trying to load the imageView in the debugger, but the image is never displayed in the imageView. Can anyone tell me what I've got wrong here?
Thanks a bunch.

You're writing out an NSData object, not an image. You need to read the NSData object back in and convert to UIImage.
Assuming everything else is correct, try this:
NSData *data = [[NSData alloc] initWithContentsOfFile:[self.managedObject valueForKey:#"imageLocation"]];
UIImage *image = [[UIImage alloc] initWithData:data];

Using NSDateFormatterShortStyle will cause the date to be represented as (for example) 12/11/12, which will mess up your file name. It will also use a colon in the short time representation, which is illegal.
I would recommend using a more custom date format, such as:
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:locale];
[dateFormatter setDateFormat:#"yyyyMMdd-HHmmss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

I used this code on one of my test projects and simulated the bug. Jordan was right about converting it to NSData first before changing it again to UIImage but the real problem here is on your file naming method.
I noticed that you have used the current date and time as the file name of your image. This includes characters such as ":" and "/" which is not allowed to be used on file names. http://www.portfoliofaq.com/pfaq/FAQ00352.htm
As a solution, I made the date format as what is written below:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyyMddHHmm"];
NSString *imageName = [NSString stringWithFormat:#"photo-%#.png",
[dateFormatter stringFromDate:[NSDate date]]];
Hope this helps others as well. :)

Related

Reading a Text file in xcode

First off, I'm a complete beginner.
This might be a stupid question, but here it goes:
I'm currently working on an App than contains Latin texts that the users can view and read.
I'm using Xcode 4 with the storybord function.
Theway the app is built: user selects author - then the book - then app shows the text.
I am kind of confused because i need to have various text files, depending on the users choice.
As i have done or do usually just embedded the files as resource and by using the below code I read-out the files
in .h file
-(NSString *)readFile:(NSString *)fileName;
in .m file
-(NSString *)readFile:(NSString *)fileName
{
NSLog(#"readFile");
NSString *appFile = fileName;
NSFileManager *fileManager=[NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:appFile])
{
NSError *error= NULL;
NSString *resultData = [NSString stringWithContentsOfFile: appFile encoding: NSUTF8StringEncoding error: &error];
if (error == NULL)
return resultData;
}
return NULL;
}
May this will help you
Enjoy Coding :)
EDIT
What I have done is according to the date change on one button click and also at the time of viewWillApper I call the function below
-(void)dateAndContentReload
{
NSLog(#"dateAndContentReload");
NSLog(#"Appdelegate Date: %#",appDelegate.dateSelected);
self.currentDate = appDelegate.dateSelected;
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd MMMM yyyy"];
NSString *dateString = [dateFormatter stringFromDate: appDelegate.dateSelected];
self.navigationItem.title = dateString;
[dateFormatter setDateFormat: #"Myyyy"];
NSString *dateComp = [dateFormatter stringFromDate: appDelegate.dateSelected];
//NSLog(#"date : %#",dateString);
NSString *data;
NSString *path;
if(![dateComp isEqualToString: #"12012"])
{
NSString *size = [NSString stringWithFormat: #"%f",appDelegate.size] ;
NSLog(#"dateAndContentReload size: %f",appDelegate.size);
data = #"<html><body><font size='";
data = [data stringByAppendingString: size];
data = [data stringByAppendingString: #"'><P>"];
data = #"Data not Available for Current Date.";
data = [data stringByReplacingOccurrencesOfString: #"\n" withString:#"<br>"];
data = [data stringByAppendingString:#"</P></font></body></html>"];
}
else
{
[dateFormatter setDateFormat:#"MMMMd"];
dateString = [dateFormatter stringFromDate: appDelegate.dateSelected];
[dateFormatter release];
NSLog(#"new Format: %#",dateString);
path = [[NSBundle mainBundle] pathForResource: dateString ofType: #"txt"];
data = nil;
NSString *size = [NSString stringWithFormat: #"%f",appDelegate.size] ;
NSLog(#"dateAndContentReload size: %f",appDelegate.size);
data = #"<html><body><font size='";
data = [data stringByAppendingString: size];
data = [data stringByAppendingString: #"'><P>"];
data = [data stringByAppendingString: [self readFile: path]];
data = [data stringByReplacingOccurrencesOfString: #"\n" withString:#"<br>"];
data = [data stringByAppendingString:#"</P></font></body></html>"];
}
[self.currentView loadHTMLString: data baseURL: nil];
}
Basically I read file and display in UIWebView as client request it.

Memory Leak while using NSDateFormatter

I have seen many questions/answers on memory leaks in NSDateFormatter, but none seems to help me determine what is causing memory to leak in my app. Here is my code:
- (id)init
{
if ((self = [super init]))
{
items = [[NSMutableArray alloc] init];
events = [[NSMutableArray alloc] init];
buffer = [[NSMutableData alloc] init];
format = [[NSDateFormatter alloc] init];
lastFromDate = #"";
}
return self;
}
- (void)presentingDatesFrom:(NSDate *)fromDate to:(NSDate *)toDate delegate:(id<KalDataSourceCallbacks>)delegate
{
[format setTimeZone:[NSTimeZone systemTimeZone]];
[format setDateFormat:#"MM/dd/yyyy"];
NSString *stringFromDate = [NSString stringWithString:[format stringFromDate:fromDate]];
NSString *stringToDate = [NSString stringWithString:[format stringFromDate:toDate]];
NSLog(#"From date: %#, To date: %#", stringFromDate, stringToDate);
[self didDatesChange:stringFromDate];
if (dataReady) {
[callback loadedDataSource:self];
return;
}
callback = delegate;
[self retrieveEventData:stringFromDate to:stringToDate];
}
- (void)dealloc
{
[items release];
[events release];
[buffer release];
[lastFromDate release];
[format release];
[super dealloc];
}
When I run "Profile" -> "Leaks", I get a memory leak every time the function is called on line
NSString *stringFromDate = [NSString stringWithString:[format stringFromDate:fromDate]];
Can someone explain what might be going on?
thanks, mike
FYI you can change this:
NSString *stringFromDate = [NSString stringWithString:[format stringFromDate:fromDate]];
to this:
NSString *stringFromDate = [format stringFromDate:fromDate];
stringWithString should return an autoreleased NSString though so I don't believe that is the source of your leak. It looks like there is no leak in your code to me.
you just use bellow method for get string from date its work properly......
-(NSString *)StringFromDate:(NSDate *)DateLocal{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MM/dd/yyyy"];
NSString *dateString = [dateFormat stringFromDate:DateLocal];
NSLog(#"Date is HERE =====>> %#",dateString);
return dateString;
}
after when you want to get date string just use like bellow....
NSString *stringFromDate = [self stringFromDate:fromDate]];
[stringfromdate retain];
NSString *stringToDate = [self stringFromDate:toDate]];
[stringTodate retain];
and above -(NSString *)StringFromDate:(NSDate *)DateLocal method is must be define in your viewcontroller.m file....
Its work fine....

NSDate as argument in customMethod

I've defined my custom method ( -(void)loadXML {} ) into my appDelegate.
Now I'd like to use it in severals viewControllers; Right now I'm using local NSDate objects.
NSDate *todayDate = [NSDate date];
NSString *XMLUrl = #"http://localhost/MyApp/GetXML?&aDate=";
NSString *urlString = [NSString stringWithFormat:#"%#%#", XMLUrl, todayDate];
tbxml = [[TBXML alloc] initWithURL:[NSURL URLWithString:urlString]];
instead of 'todayDate' I'd like to have 'selectedDate'; also how I add a bool to my method, need to have some conditions into my method?
Here's what you can do:
NSDate *selectedDate = ???????; // set this to whatever you want selectedDate to be
BOOL myBoolean = YES;
NSDateFormatter * dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat: #"yyyy-MM-dd"]; // or whatever format you wish
NSString *urlString =
[NSString stringWithFormat:#"http://localhost/MyApp/GetXML?BOOL=%#&aDate=%#",
(myBoolean ? #"YES" : #"NO"),
[dateFormatter stringFromDate: selectedDate]];
tbxml = [[TBXML alloc] initWithURL:[NSURL URLWithString:urlString]];
[dateFormatter release]; // don't forget to release, if not using ARC
And for your benefit, I'm showing you how to use a NSDateFormatter and a generic C ternary conditional.
I hope this helps you out!

How can I take snapshot of the whole context I drew in quartz 2d

I want to take a thumbnail preview of what the user will watch on clicking a button. Or if this is not possible is it possible to scale a context to a particular size.
My context is currently using full screen i.e 1004x768 px . And I want this whole context to come in 300x300 px without loosing its identity.
Try this
UIGraphicsBeginImageContext(CGSizeMake(self.view.frame.size.height, self.view.frame.size.width));
[self.view.layer renderInContext:UIGraphicsGetCurrentContext() ];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
NSLog(#"Screen Shot : %#",screenshot);
UIGraphicsEndImageContext();
// ATTACHING A SCREENSHOT
NSData *myData = UIImagePNGRepresentation(screenshot);
NSDate *date = [NSDate date];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"mm:ss"];
NSString *timestamp = [df stringFromDate:date];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fullImagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"Image_%#.png",timestamp]];
NSLog(#"TimeStamp = %#",timestamp);
NSLog(#"Image Path : %#",fullImagePath);
[myData writeToFile:fullImagePath atomically:YES];

Iphone Allocation with NSData

I have a method that downloads many images from the internet, then saves them to the device. Here is the code:
-(IBAction) updateImages {
for (x=0; x<[imagesToUpdate count]; x=x+1) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSMutableDictionary *tempDic = [dic objectForKey:[imagesToUpdate objectAtIndex:x]];
BOOL newDictionary = [self downloadChartForDictionary:tempDic];
[pool drain];
}
}
-(BOOL) downloadChartForDictionary:(NSMutableDictionary *)dictionary {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSMutableDictionary *updatedDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionary];
NSString *downloadString = [NSString stringWithFormat:#"http://www.photo.com/%#_0001.jpg",[updatedDictionary objectForKey:#"PDFName"]];
[updatedDictionary setObject:serverAIRAC forKey:#"airac"];
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"MM-dd-y";
NSString *dateString = [formatter stringFromDate:date];
[updatedDictionary setObject:dateString forKey:#"date"];
[formatter release];
NSURL *url = [NSURL URLWithString:downloadString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *savePath = [NSString stringWithFormat:#"%#/%#^%#_%#.jpg",docsPath,serverAIRAC,[updatedDictionary objectForKey:#"airport"],[updatedDictionary objectForKey:#"PDFName"]];
BOOL downloaded = [data writeToFile:savePath atomically:YES];
[pool drain];
return YES;
}
My problem is that when this runs, the NSData object, data, is allocated but never released, even when the updateImages method is finished. In instruments, each image that is downloaded remains allocated. The total allocations continues to rise as each image is downloaded and eventually there is a out of memory crash. Instruments does not report a leak associated with this object however.
I have tried: [[NSData alloc]initWithContentsOfURL:url] and then releasing it, but that doesn't help.
I have tried putting the autorelease pool only in the updateImages method and only in the downloadChartForDictionary method and neither helps.
I've been stuck on this all day so any help is greatly appreciated
Did you try [[[NSData alloc]initWithContentsOfURL:url] autorelease]? That will put the NSData object into the current autorelease pool. A straightforward alloc/init creation will still require your explicit management.
Try using dataWithContentsOfURL:options:error: with different reading options. I would start with NSDataReadingUncached, because it sounds like your data is being cached when you don't want it to be.
this was actually a non-issue... For some reason instruments was reporting the allocations, but when I actually ran the app, it never crashed.