I have used the code given here to save and load images
It works fine when i use it together in one view controller, but when i use the saveImage method in one view controller and try to load the image in another view controller the image returned blank...
In view controller A i use the following to save a image
- (void)saveImage: (UIImage*)image
{
NSLog(#"saveimage called");
if (image != nil)
{
NSLog(#"Image not null");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:
#"test.png" ];
NSData* data = UIImagePNGRepresentation(image);
[data writeToFile:path atomically:YES];
QrImageView.image = nil;
}
}
And in view controller say B I'm loading the image using..
- (UIImage*)loadImage
{
NSError *error;
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:
#"test.png" ];
UIImage* image = [UIImage imageWithContentsOfFile:path];
// Write out the contents of home directory to console
NSLog(#"Documents directory: %#", [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error]);
return image;
}
I also get the content of the file in console but i dont understand why the image is blank
2013-07-06 14:13:19.750 YouBank[500:c07] Documents directory: (
"test.png"
)
Any idea what I'm doing wrong...
EDIT:
In the view controller B on the viewDidload method i do the following
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
ImageView.image=[self loadImage];
ImageName.text = #"Cash Withdrawal";
}
The problem is that you're updating your UIImageView with the UIImage only upon viewDidLoad. You need to add an update once you are done obtaining it from the filesystem (preferably on a background thread). So it would look something like this:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
UIImage *loadedImage = [self loadImage];
dispatch_async(dispatch_get_main_queue(),^{
ImageView.image = loadedImage;
});
});
I would also recommend to use names starting with lowercase characters for instance names, so you should rename ImageView -> imageView
try this
//Document Directory
#define kAppDirectoryPath NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
#pragma mark - File Functions - Document/Cache Directory Functions
-(void)createDocumentDirectory:(NSString*)pStrDirectoryName
{
NSString *dataPath = [self getDocumentDirectoryPath:pStrDirectoryName];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:NULL];
}
-(NSString*)getDocumentDirectoryPath:(NSString*)pStrPathName
{
NSString *strPath = #"";
if(pStrPathName)
strPath = [[kAppDirectoryPath objectAtIndex:0] stringByAppendingPathComponent:pStrPathName];
return strPath;
}
When your write photo
[self createDocumentDirectory:#"MyPhotos"];
NSString *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:strImageName];
[UIImagePNGRepresentation(imgBg.image) writeToFile:pngPath atomically:YES];
When you get the file
Edit
NSError *error = nil;
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[FunctionManager getDocumentDirectoryPath:#"MyPhotos"] error:&error];
if (!error) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self ENDSWITH '.png'"];
NSArray *imagesOnly = [dirContents filteredArrayUsingPredicate:predicate];
for (int i=0;i<[imagesOnly count]; i++) {
[arrSaveImage addObject:[imagesOnly objectAtIndex:i]]; //arrSaveImage is Array of image that fetch one by one image and stored in the array
}
}
NSString *strPath=[self getDocumentDirectoryPath:#"MyPhotos"]; // "MyPhotos" is Your Directory name
strPath=[NSString stringWithFormat:#"%#/%#",strPath,[arrSaveImage objectAtIndex:i]]; //You can set your image name instead of [arrSaveImage objectAtIndex:i]
imgBackScroll.image=[UIImage imageWithData:[NSData dataWithContentsOfFile:strPath]];
it may help you.
Related
I have the following code, I don't want to get into why I am doing it this way, but for some reason this is not working. The stringURL is working fine, it gets data back, but fails to write to the document directory. This is the first time I'm working with files, and have been pulling my hair out trying to get this to work. Please could someone point me in the right direction?
+ (void) downloadAndStorePDFFromURLWithString: (NSString *) stringURL andFileID: (NSString *) fileID andTitle: (NSString *) title;
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *pdfData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: stringURL]];
dispatch_async(dispatch_get_main_queue(), ^(void) {
//STORE THE DATA LOCALLY AS A PDF FILE
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
documentsDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat: #"%#/%#", fileID, title]];
//GET LOCAL FILE PATH OF DOWNLOADED PDF
//NSLog(#"SUCCESSFULLY DOWNLOADED DOCUMENT FOR FILE: %# WILL BE STORED AT %#", fileID, documentsDirectory);
BOOL success = [pdfData writeToFile: documentsDirectory atomically: YES];
NSLog(success ? #"Yes" : #"No");
//TELL TABLEVIEW TO RELOAD
//[[NSNotificationCenter defaultCenter] postNotificationName: #"DocumentDownloaded" object: nil];
//SAVE FILEPATH URL IN NSUSERDEFAULTS
//[PDFDownloadManager addURLToListOfSavedPDFs: [PDFDownloadManager filePath: fileID andTitle: title] andFileID: fileID];
});
});
}
You are attempting to write the file to a subfolder of the Documents folder. This is failing because the subfolder doesn't exist. You need to create the folder before you can write to it.
You should also clean up the code a bit. And use the better NSData method to write the file.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *folder = [documentsDirectory stringByAppendingPathComponent:fileID];
[[NSFileManager defaultManager] createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:nil error:nil];
NSString *filePath = [folder stringByAppendingPathComponent:title];
NSError *error = nil;
BOOL success = [pdfData writeToFile:filePath options: NSDataWritingAtomic error:&error];
if (!success) {
NSLog(#"Error writing file to %#: %#", filePath, error);
}
How can I retrieve all the images from NSDocumentsDirectory? I don't know the image name but I need to store all the images in NSMutableArray.
Try this dude
-(NSMutableArray*)pullOutAllImagesInDocumentsDirectory{
NSArray *listOfPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [listOfPaths objectAtIndex:0];
NSArray *filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
NSMutableArray *imageFilePathsCollection = [[NSMutableArray alloc] init];
for (int imageIndex=0; imageIndex<filePathsArray.count; imageIndex++) {
NSString *strFilePath = [filePathsArray objectAtIndex:0];
if ([[strFilePath pathExtension] isEqualToString:#"png"]||
[[strFilePath pathExtension] isEqualToString:#"PNG"]||
[[strFilePath pathExtension] isEqualToString:#"jpg"]) {
[imageFilePathsCollection addObject:[filePathsArray objectAtIndex:imageIndex]];
}
}
return imageFilePathsCollection;
}
NOTE: it will give image url path. in order to get the image, you can use
[yourImageView setImage:[UIImage imageWithContentsOfFile:"Path Of Image"]];
I assuming you mean the Documents Directory specific to your app sandbox. If so you can access that directory using [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
Cycle through that directory and look for files that have a .png or .jpg e.t.c. path extension.
i.e:
NSString *string = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSArray *array = [[NSFileManager defaultManager] contentsAtPath:string];
for (NSString *doc in array) {
NSLog(#"%#", doc);
if ([doc.pathExtension isEqualToString:#"jpg"]) {
// Is jpg image obviously you want to search for different formats also
}
}
The following code works without error or exception - but still, it does not do what it should ! I wanted to save an image into the iOS library/Application Support folder. More precisely, the image should be placed into a /library/Application Support/bundleID_name/subfolder/ (and the subfolder being called "location1").
If I check the functionality with the iOS-Simulator, I can see the creation of the subfolder (i.e. .../library/Application Support/bundleID_name/location1/). Also the function "saveImage" works without exception. But there is no image being saved !!!! (i.e.the image-file is missing and the folder remains empty) !!
What could be the mistake ??
Here is my code with the call of two functions (see code below):
UIImage *in_image = [UIImage imageNamed:#"template009c.jpg"];
NSString *locDirectoryName = #"location1";
NSURL *LocationDirectory = [self appendLocationToApplicationDirectory:locDirectoryName];
[self saveImage:in_image :#"image1" :LocationDirectory];
With the corresponding function-Nr1:
- (NSURL*)appendLocationToApplicationDirectory:(NSString*)locationDirName
{
NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier];
NSFileManager*fm = [NSFileManager defaultManager];
NSURL* dirPath = nil;
// Find the application support directory in the home directory.
NSArray* appSupportDir = [fm URLsForDirectory:NSApplicationSupportDirectory
inDomains:NSUserDomainMask];
if ([appSupportDir count] > 0) {
// Append the bundle ID and the location-Foldername to the URL for the Application Support directory
dirPath = [[[appSupportDir objectAtIndex:0] URLByAppendingPathComponent:appBundleID] URLByAppendingPathComponent:locationDirName];
// If the directory does not exist, this method creates it.
// This method call works in OS X 10.7 and later only.
NSError* theError = nil;
if (![fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES attributes:nil error:&theError]) {
// Handle the error.
NSLog(#"%#", theError.localizedDescription);
return nil;
}
else {
// Mark the directory as excluded from iCloud backups
if (![dirPath setResourceValue:#YES
forKey:NSURLIsExcludedFromBackupKey
error:&theError]) {
NSLog(#"Error excluding %# from iCloud backup %#", [dirPath lastPathComponent], theError.localizedDescription);
}
else {
NSLog(#"Location Directory excluded from iClud backups");
}
}
}
return dirPath;
}
And function Nr2:
//saving an image
- (void)saveImage:(UIImage*)image :(NSString*)imageName :(NSURL*)pathName {
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];
// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *LocationDirectory = [pathName absoluteString];
NSString *fullPath = [LocationDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", imageName]];
/***** THE FOLLOWING LINE DOES NOT SEEM TO DO WHAT IT IS SUPPOSED TO *******/
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil];
/**** I also tried without the FileManager, but same problem - no file written... ***/
// [imageData writeToFile:fullPath atomically:NO];
NSLog(#"image saved");
}
By the way, getting the "fullPath" with the XCode-Debugger, I get:
"fullPath NSPathStore2 * #"file:/Users/username/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/2BCC3345-9M55F-4580-A1E7-6694E33456777/Library/Application%20Support/bundleID_name/image1.png" 0x09d50950
Doesn't that also seem correct ?? But why is [fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; not performing ???
This:
"fullPath NSPathStore2 * #"file:/Users/username/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/2BCC3345-9M55F-4580-A1E7-6694E33456777/Library/Application%20Support/bundleID_name/image1.png" 0x09d50950
is not a valid path, it's a URL path but stored in a string. If you are going to use URL's then use ULRs rather than trying to convert to a string:
[imageData writeToURL:pathName atomically:YES];
(preferably naming the parameter as pathURL) and if you want to use paths then don't use a URL at any stage.
Also, where an API method returns an error or status flag, check it in the code as standard.
I'm pretty sure you can't save an image on a path you specify. You can save images on the gallery or in DocumentDirectory. This should be the code to save an image on the DocumentDirectory:
NSString *imgName=[#"imgname.png"];
[[NSUserDefaults standardUserDefaults]setValue:imgName forKey:#"imageName"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:imgName];
UIImage *image = imageView.image; // imageView is my image from camera
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:NO];
I've created folder called "Image store" using the following code. my requirment is i want to save images to the folder "Image store" on api success and the images should be saved in application itself not in database or photo album.I want to know the mechanism by which i can store images in application
-(void) createFolder {
UIImage *image = [[UIImage alloc]init];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/ImageStore"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];
else
{
}
}
//Make a method that has url (fileName) Param
NSArray *documentsDirectory =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:url];
NSFileManager *fileManager =[NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:textPath])
{
return YES;
}
else
{
return NO;
}
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage
imageNamed:#""]];//Placeholder image
if ([url isKindOfClass:[NSString class]])
{
imgView.image = [UIImage imageNamed:[url absoluteString]];
imgView.contentMode = UIViewContentModeScaleAspectFit;
}
else if ([fileManager fileExistsAtPath:url])
{
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:url];
NSError *error = nil;
NSData *fileData = [NSData dataWithContentsOfFile:textPath options:NSDataReadingMappedIfSafe error:&error];
if (error != nil)
{
DLog(#"There was an error: %#", [error description]);
imgView.image=nil;
}
else
{
imgView.image= [UIImage imageWithData:fileData]
}
}
else
{ UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
CGPoint center = imgView.center;
// center.x = imgView.bounds.size.width / 2;
spinner.center = center;
[spinner startAnimating];
[imgView addSubview:spinner];
dispatch_queue_t downloadQueue = dispatch_queue_create("iamge downloader", NULL);
dispatch_async(downloadQueue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
[spinner removeFromSuperview];
UIImage *image = [UIImage imageWithData:imgData];
NSError *error = nil;
[imgData writeToFile:url options:NSDataWritingFileProtectionNone error:&error];
if (error != nil)
{
}
else
{
}
imgView.image = image;
});
});
}
Thats UIImageView loading an image if it doesnot exist in document then it Save it , An Activity indicator is added to show image is loading to save,
u can do something like this
u can run a loop for images like this
//at this point u can get image data
for(int k = 0 ; k < imageCount; k++)
{
[self savePic:[NSString stringWithFormat:#"picName%d",k] withData:imageData];//hear data for each pic u can send
}
- (void)savePic:(NSString *)picName withData:(NSData *)imageData
{
if(imageData != nil)
{
NSString *path = [NSString stringWithFormat:#"/ImageStore/%#.png",pincName];
NSString *Dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pngPath = [NSString stringWithFormat:#"%#%#",Dir,path]; //path means ur destination contain's this format -> "/foldername/picname" pickname must be unique
if(![[NSFileManager defaultManager] fileExistsAtPath:[pngPath stringByDeletingLastPathComponent]])
{
NSError *error;
[[NSFileManager defaultManager] createDirectoryAtPath:[pngPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:&error];
if(error)
{
NSLog(#"error in creating dir");
}
}
[imageData writeToFile:pngPath atomically:YES];
}
}
after successful download and saving u can retrieve images like below
- (UIImage *)checkForImageIn:(NSString *)InDestination
{
NSString *Dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pngPath = [NSString stringWithFormat:#"%#%#",Dir,InDestination];//hear "InDestination" format is like this "/yourFolderName/imagename" as i said imagename must be unique .. :)
UIImage *image = [UIImage imageWithContentsOfFile:pngPath];
if(image)
{
return image;
}
else
return nil;
}
link to find path
see this link to find the path ..
aganin do same this run loop like below
NSMutableArray *imagesArray = [[NSMutableArray alloc]init];
for(int k = 0 ; k < imageCount; k++)
{
UIImage *image = [self checkForImageIn:[NSString stringWithFormat: #"/yourFolderName/ImageName%d",k]];//get the image
[imagesArray addObject:image];//store to use it somewhere ..
}
Write this code after creating directory
NSString *path= [documentsDirectory stringByAppendingPathComponent:#"/ImageStore"];
UIImage *rainyImage =[UImage imageNamed:#"rainy.jpg"];
NSData *Data= UIImageJPEGRepresentation(rainyImage,0.0);
[data writeToFile:path atomically:YES]
The document directory is found like this:
// Let's save the file into Document folder.
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
// If you go to the folder below, you will find those pictures
NSLog(#"%#",docDir);
NSLog(#"saving png");
NSString *pngFilePath = [NSString stringWithFormat:#"%#/test.png",docDir];
Thats just a sample of the code provided which tells you where the correct path is to save in your ipone device.
Check the below blog post,it's step by step guide with source code .
Download an Image and Save it as PNG or JPEG in iPhone SDK
I have a CSV file that I'm downloading from an S3 account and I would like to show it in my ios app by using the Quicklook framework.
The error I'm getting is in my console. It says
QLPreviewController's datasource shouldn't be nil at this point.
This appears after this line of code runs // Set data source
[previewer setDataSource:self];
here's all the code for downloading the file, saving it and then loading with quicklook
-(void)showDocument
{
NSString *stringURL = #"http://jornada.s3.amazonaws.com/Dust.csv";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:nil];
if ( urlData )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"tempfile.csv"];
//[urlData writeToFile:filePath atomically:YES];
BOOL newFile = [[NSFileManager defaultManager] createFileAtPath:filePath contents:urlData attributes:nil];
arrayOfDocuments = [[NSArray alloc] initWithObjects:
filePath, nil];
QLPreviewController *previewer = [[QLPreviewController alloc] init];
[self addSubview:previewer.view];
// Set data source
[previewer setDataSource:self];
// Which item to preview
[previewer setCurrentPreviewItemIndex:0];
}
}
/*---------------------------------------------------------------------------
*
*--------------------------------------------------------------------------*/
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return [arrayOfDocuments count];
}
/*---------------------------------------------------------------------------
*
*--------------------------------------------------------------------------*/
- (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
// Break the path into it's components (filename and extension)
NSArray *fileComponents = [[arrayOfDocuments objectAtIndex: index] componentsSeparatedByString:#"."];
NSArray *filePaths = [[fileComponents objectAtIndex:0] componentsSeparatedByString:#"/"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[((NSString *)[filePaths objectAtIndex:[filePaths count]-1]) stringByAppendingString:(NSString*)[fileComponents objectAtIndex:1]]];
// Use the filename (index 0) and the extension (index 1) to get path
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
if (fileExists) {
//
}
return [NSURL fileURLWithPath:filePath isDirectory:NO];
}
You don't add a preview controller's view to your view - you present the preview controller. And you should do that after setting the data source! So, in this order:
QLPreviewController* preview = [QLPreviewController new];
preview.dataSource = self;
[self presentViewController:preview animated:YES completion:nil];