So I have a function which gets an image from a URL which looks like this:
- (UIImage *) getImageFromURL:(NSString *)fileURL {
UIImage * result;
NSData * img_data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
result = [UIImage imageWithData:img_data];
return result;
}
and then a function which saves the image from a UIImage Which looks like this:
-(void) saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
if ([[extension lowercaseString] isEqualToString:#"png"]) {
[UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", imageName, #"png"]] options:NSAtomicWrite error:nil];
} else if ([[extension lowercaseString] isEqualToString:#"jpg"] || [[extension lowercaseString] isEqualToString:#"jpeg"]) {
[UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", imageName, #"jpg"]] options:NSAtomicWrite error:nil];
NSLog(#"Image named %# wrote to %#", imageName, directoryPath);
} else {
NSLog(#"Image Save Failed\nExtension: (%#) is not recognized, use (PNG/JPG)", extension);
}
}
The issue I am facing is that when I run a UIImage through the saveImage function I dont think it is saving the image. This is because when I check for a UIImage imageNamed:#"Documents/filenamesavedas.jpeg" it returns (null). The image does however download correctly.
Here is my Documents Directory path function:
- (NSString *)getDocumentsDirectoryPath {
NSString * documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSLog(documentsDirectoryPath);
return documentsDirectoryPath;
}
Here is where I am downloading and trying to save the image:
dispatch_async(jsonQueue, ^{
// check to see if data authenticate runs successfully.
NSString *documentsDirectoryPath = [util getDocumentsDirectoryPath];
UIImage *imageToSave = [util getImageFromURL:[properties objectForKey:#"current_group_logoURL"]];
[util saveImage:imageToSave withFileName:[properties objectForKey:#"home_venue_logo"] ofType:#"jpeg" inDirectory:documentsDirectoryPath];
NSLog(#"Group Logo URL %#", [properties objectForKey:#"current_group_logoURL"]);
NSLog(#"Current Group Image %#", [properties objectForKey:#"home_venue_logo"]);
UIImage *testToSeeItHasDownloaded = imageToSave;
NSString *imageLocation = [documentsDirectoryPath stringByAppendingPathComponent:[properties objectForKey:#"home_venue_logo"]];
NSData *data = [NSData dataWithContentsOfFile:imageLocation];
UIImage *testToSeeImageHasSaved = [UIImage imageWithData:data];
NSLog(#"testToSeeImagehasDownloaded: %#", testToSeeItHasDownloaded);
NSLog(#"image location to save to: %#", imageLocation);
NSLog(#"testToSeeImagehasSaved: %#", testToSeeImageHasSaved );
});
The Console returns this:
2012-10-22 16:27:45.642 asdaf[46819:1d807] Group Logo URL http://somesite.com/50a0e42619424ba551a956511c098656.jpeg
2012-10-22 16:27:45.642 asdaf[46819:1d807] Current Group Image 50a0e42619424ba551a956511c098656.jpeg
2012-10-22 16:27:45.649 asdaf[46819:1d807] testToSeeImagehasDownloaded: <UIImage: 0xb09ed50>
2012-10-22 16:27:45.649 asdaf[46819:1d807] testToSeeImagehasSaved: (null)
testToSeeImagehasSaved should return null. But what am I doing wrong? Thanks.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//documentsDirectory is your documents directory path
//Now append your image name in this path
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:#"ImageName.jpeg"];
//convert your image in NSData
NSData *imageData = UIImagePNGRepresentation(image);
//Now write it at path
[imageData writeToFile:imagePath atomically:NO];
You can get this image in same way
NSData *data = [NSData dataWithContentsOfFile:imagePath];
UIImage *image = [UIImage imageWithData:data];
Edit:
-(void)saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imageName = [imageName stringByAppendingString:extension];
//Note extension should be like .png, .jpg, .jpeg dont forget dot (.).
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:imageName];
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:imagePath atomically:NO];
}
Well i dont now about your whole code but why you're passing an UIImage object when you have to save your image in documents directory. You can pass NSData as well in your method. You're doing more.
Your problem is you're saving .jpg image each time and at the time of retrieving you're trying to find .jpeg image on same path thats why you're getting null value. See this line in your saving method -
[UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", imageName, #"jpg"]] options:NSAtomicWrite error:nil];
this line doesn't look right to me:
UIImage *testToSeeImageHasSaved = [UIImage imageNamed: [#"Documents/" stringByAppendingString: [properties objectForKey:#"home_venue_logo"]]];
I think you have to do:
UIImage* image = [UIImage imageWithContentsOfFile:"YOUR_FILE_PATH"];
[UIImage imageNamed:"image_name"] is good only for images attached to your project
When you save it in the document folder, it does not exacly saves it in the "Document" directory but rather something like
path=/var/mobile/Applications/144B3628-5258-4939-8B80-006EC5BE45B2/Library/Caches/6_1.png
So to retreive your image you should use
NSString *uniquePath = [directory stringByAppendingPathComponent: filename];
image = [UIImage imageWithContentsOfFile: uniquePath];
where directory is the path you used to save it and filename the name of your jpeg.
[UIImage imageNamed:#"Documents/filenamesavedas.jpeg"]
Doesnt take paths it searches your bundle for the file with a specific name.
Locate the file using calls to NSFileManager and use the expected path and file name.
Related
I need to check if an image exists in the project navigator. If it doesn't it needs to download it from the internet. The goal is to be able to use images like [UIImage imageNamed:#"23451.jpg"];
So I need to check if the image exists, if not download it. I tried to do this as followed:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//Set image
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:#"12345.jpg"];
//Check if the image exists at a given path
BOOL imageExists = [[NSFileManager defaultManager] fileExistsAtPath:imagePath];
//If the image doesn't exists download it.
if (!imageExists)
{
NSData* data = UIImageJPEGRepresentation([UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"www.mywebsite.com/12345.jpg"]]]);
[data writeToFile:imagePath atomically:YES];
}
If everything goes the right way the image is saved at the above path. But I still am not able to use this image with
[UIImage imageNamed:#"12345.jpg"];
I have got the feeling that i'm saving the images in a different directory than I should be saving them to.
Do you have any idea on how I should do this?
imageNamed will only work form image in the app bundle, not those stored in the Document directory. And you can't add the image to the app bundle, it readonly.
if (!imageExists)
{
NSData* data = UIImageJPEGRepresentation([UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"www.mywebsite.com/12345.jpg"]]]);
[data writeToFile:imagePath atomically:YES];
}
There is no need to do this, you are now JPG a JPG:
if (!imageExists)
{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.mywebsite.com/12345.jpg"]];
[data writeToFile:imagePath atomically:YES];
}
NSData* data = [NSData dataWithData:UIImageJPEGRepresentation([UIImage imageWithContentsOfFile:imagePath], 0.8)];
[data writeToFile:imagePath atomically:YES];
I did something similar .. here are some excerpts of the code .. not the complete code ...
- (void)loadAndStoreImage{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSURL *theurlPortrait = [[NSURL alloc] initWithString:[[DataController sharedDataController].imageResponse objectForKey:#"portraitImageUrl"] ];
NSLog(#"Image url %# ",theurlPortrait);
imageDataPortrait = [NSData dataWithContentsOfURL:theurlPortrait];
[theurlPortrait release];
imagePortrait= [[UIImage alloc]initWithData:imageDataPortrait];
oldPathPortrait = [documentsDirectory stringByAppendingPathComponent:#"pt_wallpaper_1.png"];
NSURL *theurlLandscape = [[NSURL alloc] initWithString:[[DataController sharedDataController].imageResponse objectForKey:#"landscapeImageUrl"]];
imageDataLandscape = [NSData dataWithContentsOfURL:theurlLandscape];
[theurlLandscape release];
imageLandscape= [[UIImage alloc]initWithData:imageDataLandscape];
oldPathLandscape = [documentsDirectory stringByAppendingPathComponent:#"ls_wallpaper_1.png"];
[self replaceImages];
}
-(void)replaceImages{
//check if images were fully downloaded or corrupted.
if (isUserSignedIn) {
if (imageDataPortrait && imageDataLandscape) {
[UIImagePNGRepresentation(imagePortrait) writeToFile:oldPathPortrait atomically:YES];
[UIImagePNGRepresentation(imageLandscape) writeToFile:oldPathLandscape atomically:YES];
NSLog(#"IMAGES REPLACED");
NSDate *currentDate=[NSDate date];
[[ NSUserDefaults standardUserDefaults] setObject:currentDate forKey:#"previousDate"];
}
}
}
I have pulled an image out of the UIImagePicker thingy, and I would like to temporarily save it to the sandbox environment, in either the documents folder, or some other similar equivalent. However, I do not know how to do this, please could someone help me? Thanks
At the moment the image is a UIImage
Saving an image:
-(void)saveImage:(UIImage*)image{
NSString *imagePath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/someImageName.png"];
[UIImagePNGRepresentation(image) writeToFile:imagePath atomically:YES];
}
Loading an image
-(UIImage)loadImage{
NSString *imagePath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/someImageName.png"];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
}
-(void)SaveImage
{
NSData *data;
NSArray *paths;
NSString *documentsDirectory,*imagePath ;
UIImage *image=[UIImage imageNamed:#"public.png"];
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"public.png"]];
data = UIImagePNGRepresentation(image);
[data writeToFile:imagePath atomically:YES];
}
I am saving the images when there is internet connection in my iphone.
Now i want to load the images which are saved in documents directory. I am getting the path, but the image is not displaying. Please help me in this.
Thanks in advance.
Here is my code:
+(UIImage *) getImagewithName:(NSString*) imagepath
{
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
UIImage *gimage=[UIImage imageWithContentsOfFile: [NSString stringWithFormat:#"%#/%#",docDir,imagepath]];
NSLog(#"%#/%#",docDir,imagepath);
return gimage;
}
+(void)DownloadImage:(NSString*)ImagePath {
if ([ImagePath isEqualToString:#""])
return;
UIImage *dimage = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http:/uploads/%#",ImagePath]]]];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSLog(#"pathIMAGEPATHS:::::::%#",ImagePath);
NSLog(#"path:::::::%#",docDir);
NSArray *patharr=[ImagePath componentsSeparatedByString:#"."];
NSString* Ext=[NSString stringWithFormat: #"%#",[patharr objectAtIndex:1]];
NSString *FilePath = [NSString stringWithFormat: [NSString stringWithFormat:#"%#/%#",docDir,ImagePath]];
if([Ext isEqualToString:#"png"])
{
NSLog(#"saving png");
NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(dimage)];
[data1 writeToFile:FilePath atomically:YES];
}
else if([Ext isEqualToString:#"jpeg"])
{
NSLog(#"saving jpeg");
//NSString *jpegFilePath = [NSString stringWithFormat:#"%#/test.jpeg",docDir];
NSData *data2 = [NSData dataWithData:UIImageJPEGRepresentation(dimage, 1.0f)];//1.0f = 100% quality
[data2 writeToFile:FilePath atomically:YES];
}
else
{
NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(dimage)];
[data1 writeToFile:FilePath atomically:YES];
}
NSLog(#"saving image done");
[dimage release];
}
viggio24 makes a good point. But moreover, this code seems incredibly complicated to do something incredibly simple. Why do you download to data, then turn it into an image, just to turn it back into data, and finally write it? And then you read it again and make a new image? Why not just download the file to disk and read it? UIImage will do all the work of managing PNG and JPEG for you. Something like:
+(void)downloadImage:(NSString*)imagePath {
if ([imagePath isEqualToString:#""])
return;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[#"http://110.234.132.132/MBCMcAdmin/uploads" stringByAppendingPathComponent:imagePath]]];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
[data writeToFile:[docDir stringByAppendingPathComponent:imagePath] atomically:YES];
}
This is still a horrible idea in most cases, though, since it blocks the calling thread. It's better to do this with NSURLDownload which will do it all for you in the background and tell you when it's done.
I'd simplify the code, and then follow viggio24's comments, making sure that you error check this stuff. You're probably just not reading the file correctly or failing to write it.
I am using a UIImagePickerController, and once an image is selected, I save it to a PNG. But for some reason, I can't load the saved image.
Here is my code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
//
// Create a PNG representation of the edited image
//
UIImage *anImage = [info valueForKey:UIImagePickerControllerEditedImage];
NSData *imageData = UIImagePNGRepresentation(anImage);
//
// Save the image to the documents directory
//
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// Get a unique filename for the file
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
NSString *fileName = [(NSString *)string autorelease];
fileName = [NSString stringWithFormat:#"images/%#", fileName];
fileName = [fileName stringByAppendingString:#".png"];
NSString *path = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithString:fileName] ];
[imageData writeToFile:path atomically:YES];
NSLog(#"Wrote the imageData to a file at path: %#", path);
// TEST TO SEE IF THE FILE WAS WRITTEN CORRECTLY
UIImage *testImage = [UIImage imageWithContentsOfFile:path];
NSLog(#"testImage is %#", testImage);
And here is my debugger output:
2010-12-28 16:29:08.676 Appster[6656:207] The imagePath is defined as: images/7ADB104E-DA45-4EE9-88DA-FF71B8D730CA.png
2010-12-28 16:29:08.712 Appster[6656:207] Wrote the imageData to a file at path: /Users/bschiff/Library/Application Support/iPhone Simulator/4.2/Applications/9F6FC2C7-9369-438C-AF8F-D5D25C72D8D7/Documents/images/FC94AA93-02EC-492A-A8FE-7D0C76E2C085.png
2010-12-28 16:29:08.715 Appster[6656:207] testImage is (null)
Have you tried to use NSBundle to refer to your resources path?
Try this one:
[[NSBundle mainBundle] pathForResource:[NSString stringWithString:fileName]
ofType:#"png" inDirectory:#"images"]]
Use that path to save and retrieve the image file
I am using a UIImagePickerController in my application.
After selecting an image by user,
image should be saved at application Documents Directory,
my Code is Give Below.
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
[picker dismissModalViewControllerAnimated:YES];
NSData *imgData = UIImagePNGRepresentation([info objectForKey:#"UIImagePickerControllerOriginalImage"]);
UIImage *img = [[UIImage alloc] initWithData:imgData];
stuImgView.image = img;
[img release];
//write image
NSString *imageFilename = [NSString stringWithFormat:#"%i.jpg", currentStudent.stuNo];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [NSString stringWithFormat:#"%#/%#", [paths objectAtIndex:0], imageFilename];
UIImage *stuImg;
BOOL success;
NSFileManager *fm=[NSFileManager defaultManager];
// how to store file at documents dir????
}
i dont know how to use file manager to store a file?
Help me Out.
Thanks in advance.
You can use writeToFile:atomically::
[imgData writeToFile:path atomically:NO];