Pictures put into a array Ios developing - iphone

I have a folder with pictures in my project and i like to know how i could put this pictures from the folder into a array
How should i do that?
I tried this to put the images in the array
UIImage*image = [[NSBundle mainBundle]pathsForResourcesOfType:#"jpg" #"jpeg" #"gif" inDirectory:#"Images"];
NSArray*images = [[NSMutableArray alloc]initWithContentsOfFile:image];

You could do the following, getting the array of filenames and then filling another array with the images, themselves (assuming that's what you were trying to do).
NSMutableArray *imagePaths = [[NSMutableArray alloc] init];
NSMutableArray *images = [[NSMutableArray alloc] init];
NSArray *imageTypes = [NSArray arrayWithObjects:#"jpg", #"jpeg", #"gif", nil];
// load the imagePaths array
for (NSString *imageType in imageTypes)
{
NSArray *imagesOfParticularType = [[NSBundle mainBundle]pathsForResourcesOfType:imageType
inDirectory:#"Images"];
if (imagesOfParticularType)
[imagePaths addObjectsFromArray:imagesOfParticularType];
}
// load the images array
for (NSString *imagePath in imagePaths)
[images addObject:[UIImage imageWithContentsOfFile:imagePath]];
As an aside, unless these are tiny thumbnail images and you have very few, it generally would not be advisable to load all the images at once like this. Generally, because images can take up a lot of RAM, you would keep the array of filenames, but defer the loading of the images until you really need them.
If you don't successfully retrieve your images, there are two questions:
Are the files included in my bundle? When you select the "Build Phases" for your Target's settings and expand the "Copy Bundle Resources" (see the image below), do you see your images included? If you don't see your images in this list, they won't be included in the app when you build it. To add your images, click on the "+" and add them to this list.
Are the files in a "group" or in an actual subdirectory? When you add files to a project, you'll see the following dialog:
If you chose "Create folder references for added folders", then the folder will appear in blue in your project (see the blue icon next to my "db_images" folder in the preceding screen snapshot). If you chose "create groups for added folders", though, there will be the typical yellow icon next to your "Images" group. Bottom line, in this scenario, where you're looking for images in the subdirectory "Images", you want to use the "Create folder references for added folders" option with the resulting blue icon next to the images.
Bottom line, you need to ensure the images are in your app bundle and that they are where you think they are. Also note that iOS is case sensitive (though the simulator is not), so make sure you got the capitalization of "Images" right.

If I am understanding your question correctly initWithContentsOfFile doesn't do what you are expecting, per the documentation:
"Initializes a newly allocated array with the contents of the file specified by a given path."
Additionally, pathsForResourceOfType is already creating an array, not a UIImage, you can simply do:
NSArray* images = [[NSBundle mainBundle]pathsForResourcesOfType:#"jpg" #"jpeg" #"gif" inDirectory:#"Images"];

[[NSBundle mainBundle]pathsForResourcesOfType:#"jpg" #"jpeg" #"gif" inDirectory:#"Images"];
already returns an array of these objects. Change your line to this:
NSArray *images = [[NSBundle mainBundle]pathsForResourcesOfType:#"jpg" #"jpeg" #"gif" inDirectory:#"Images"];
Note that this array will only hold the paths for all your images. In order to make images of them you need to call
for(NSString* imagePath in images) {
UIImage* anImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
//do something with your image here.
}
Hope that helps

Read the documentation of initWithContentsOfFile method of NSArray:
The array representation in the file identified by aPath must contain only property list objects (NSString, NSData, NSArray, or NSDictionary objects). The objects contained by this array are immutable, even if the array is mutable.
In your case you need to use NSFileManager to enumerate files in directory. Here is the example of directory enumeration from documentation:
NSFileManager *localFileManager=[[NSFileManager alloc] init];
NSDirectoryEnumerator *dirEnum =
[localFileManager enumeratorAtPath:docsDir];
NSString *file;
while (file = [dirEnum nextObject]) {
if ([[file pathExtension] isEqualToString: #"doc"]) {
// Create an image object here and add it to
// mutable array
}
}
[localFileManager release];

Try this:
NSMutableArray* paths=[NSMutableArray new];
NSFileManager* manager=[NSFileManager new];
NSBundle* bundle= [NSBundle mainBundle];
NSDirectoryEnumerator* enumerator= [manager enumeratorAtPath: [bundle bundlePath] ];
for(NSString* path in enumerator)
{
if([path hasSuffix: #".jpg"] || [path hasSuffix: #".jpeg"] || [path hasSuffix: #".gif"])
{
[paths addObject: path];
}
}
For explanations I suggest that you look at NSDirectoryEnumerator documentation.

Related

How can I get relative path of the folder in my project ?(iPhone)

Suppose, I have added one folder name "Images" in my project.How can I get the path to that folder? My main intention is to get the number of pictures in "Images" folder.
You should work a bit more on your question: it assumes a lot and requires the reader to guess.
I have added one folder name "Images" in my project
So I guess this means you added it as a folder reference
and I want to get it's path
And I guess that you want to do that at run time from your application, not at build-time from Xcode.
If so, you could do something like:
NSURL *containingURL = [[NSBundle mainBundle] resourceURL];
NSURL *imageURL = [containingURL URLByAppendingPathComponent:#"Images" isDirectory:YES];
NSFileManager *localFileManager = [[NSFileManager alloc] init];
NSArray *content = [localFileManager contentsOfDirectoryAtURL:imageURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsSubdirectoryDescendants error:NULL];
[localFileManager release];
NSUInteger imageCount = [content count];
This code does not assume that all images are of the same kind.
[[[NSBundle mainBundle] pathsForResourcesOfType:#"jpg" inDirectory:#"Images"] count];
This returns the number of jpg images from the Images folder. This is the case if you added the images to your application bundle.

Need help creating .plist in app

My app ships with a .plist that looks like this:
I want the user to be able to add a custom exerciseName.
So I need to create a new .plist in the user's document folder that mimics this format. Can anyone help me with this?
I need something like this (pseudo code)
if (userData == nil)
{
then create the .plist file;
setup the .plist to mimic the format of the img above.
}
now save exerciseName appropriately.
Update:
if (exerciseArray == nil)
{
NSString *path = [[NSBundle mainBundle]pathForResource:#"data" ofType:#"plist"];
NSMutableArray *rootLevel = [[NSMutableArray alloc]initWithContentsOfFile:path];
self.exerciseArray = rootLevel;
[rootLevel release];
}
What you will want to do is load the Plist into an NSDictionary, and encode that NSDictionary back to a Plist file in your applications document folder. In your applicationDidFinishLoading: method, I would do something like this:
NSString * documentFile = [NSHomeDirectory() stringByAppendingFormat:#"/Documents/myPlist.plist"];
if (![[NSFileManager defaultManager] fileExistsAtPath:documentFile]) {
// create a copy of our resource
NSString * resPath = [[NSBundle mainBundle] pathForResource:#"myPlist" ofType:#"plist"];
// NOTE: replace #"myPlist" with the name of the file in your Resources folder.
NSDictionary * dictionary = [[NSDictionary alloc] initWithContentsOfFile:resPath];
[dictionary writeToFile:documentFile atomically:YES];
[dictionary release];
}
Then, when you want to add an item, you want to use an NSMutableDictionary to modify and save the existing plist in the app's documents directory:
- (void)addExercise {
NSMutableDictionary * changeMe = [[NSMutableDictionary alloc] initWithContentsOfFile:documentFile];
... make changes ...
[changeMe writeToFile:documentFile atomically:YES];
[changeMe release];
}
To make changes, you will need to find the sub-dictionary containing the array of exercises. Then use the setObject:forKey: method on the NSMutableDictionary to set a new array containing a new list of exercises. This might look something like this:
NSMutableArray * list = [NSMutableArray arrayWithArray:[changeMe objectForKey:#"list"]];
NSArray * exercises = [[list objectAtIndex:10] objectForKey:#"exercises"];
NSDictionary * newExercise = [NSDictionary dictionaryWithObject:#"Type a LOT" forKey:#"exerciseName"];
exercises = [exercises arrayByAddingObject:newExercise];
NSMutableDictionary * dict = [NSMutableDictionary dictionaryWithDictionary:[list objectAtIndex:10]];
[dict setObject:exercises forKey:#"exercises"];
[list replaceObjectAtIndex:10 withObject:dict];
[changeMe setObject:list forKey:#"list"];
Once you make your change, it is important to remember to write changeMe to the plist file in the documents directory.
The easiest way to read and write property lists is to use the NSArray or NSDictionary classes. Your screenshot appears to be an array at the top level, so I will use that assumption for my examples.
First you need paths to the user file and original file.
NSString *pathToUserFile; // Get a path to the file in the documents directory
NSString *pathToDefaultFile; // Get a path to the original file in the application bundle
You then attempt to load the
NSMutableArray *userData;
NSArray *temporary = [NSArray arrayWithContentsOfFile:pathToUserFile];
if(!temporary) temporary = [NSArray arrayWithContentsOfFile:pathToDefaultFile];
Since it appears that you are using multiple layers containers, I am assuming that you will need the innermost arrays and dictionaries to be mutable. The normal initialization of NSMutableArray will not do this, so you need to use CFPropertyListCreateDeepCopy with the options set to have mutable containers.
userData = (NSMutableArray *)CFPropertyListCreateDeepCopy(NULL,(CFArrayRef)temporary,kCFPropertyListMutableContainers);
You now have a mutable object representing your data. You can add objects or modify existing objects the same way you handle any array, but you can only add strings, numbers, data objects, dictionaries, arrays, and dates, since those are the only types valid in property lists.
[userData addObject:newDataObject];
Finally, you write the data out to the file in the documents directory. The writeToFile:atomically: method will attempt to write out a property list, and return YES if successful. It will fail and return NO if the file could not be written, or if the contents are not all valid property list objects.
if(![userData writeToFile:pathToUserFile atomically:YES]) {
NSLog(#"Error writing to file");
}

imageNamed is evil - How to use the function

- (UIImage*)thumbnailImage:(NSString*)fileName
{
UIImage *thumbnail = [thumbnailCache objectForKey:fileName];
if (nil == thumbnail)
{
NSString *thumbnailFile = [NSString stringWithFormat:#"%#/thumbnails/%#.jpg", [[NSBundle mainBundle] resourcePath], fileName];
thumbnail = [UIImage imageWithContentsOfFile:thumbnailFile];
[thumbnailCache setObject:thumbnail forKey:fileName];
}
return thumbnail;
}
I got this code from http://www.alexcurylo.com/blog/2009/01/13/imagenamed-is-evil/ . Can someone tell me how to use this code. I need just a little help how to use this in place of imageNamed.
NSMutableDictionary *thumbnailCache=[[NSMutableDictionary alloc]init];
then add "thumbnails" folder to ur resource folder then put ur png there
- (UIImage*)thumbnailImage:(NSString*)fileName
{
UIImage *thumbnail = [thumbnailCache objectForKey:fileName];
if (nil == thumbnail)
{
NSString *thumbnailFile = [NSString stringWithFormat:#"%#/thumbnails/%#.jpg", [[NSBundle mainBundle] resourcePath], fileName];
thumbnail = [UIImage imageWithContentsOfFile:thumbnailFile];
[thumbnailCache setObject:thumbnail forKey:fileName];
}
return thumbnail;
}
example
add foo.png to resource folder
//here create UIImageView object then
UIImageviewObject.image=[self thumbnailImage:#"foo.png"];
The code uses a NSMutableDictionary *thumbnailCache to cache UIImage instances. The code assumes that in the app bundle, there's a directory thumbnails with scaled down versions of their images.
The method now first looks in the thumbnailCache dictionary whether the thumbnail for the given image (which is only a filename without full path, e. g. myimage.png). If the dictionary did not contain an image already, the image is loaded from the thumbnails directory (using imageWithContentsOfFile: instead of imageNamed:, since the authors claim the later causes trouble). The loaded image is then stored in the dictionary so the next time the app asks for the thumbnail, it can use the already loaded instance.
For this code to work correctly in your app, you need to add a thumbnails folder to your project. When you add it to your project, be sure to select "Create folder references for any added folders" instead of the default "Create groups for any added folders". Only then you will get a subdirectory in your app's main bundle, otherwise all files are put into the same top-level folder.
But the whole point is that the author claims:
Avoid [UIImage imageNamed:].
Instead, have a NSMutableDictionary.
Look up images in the dictionary.
If found, use that.
If not found, load image using [UIImage imageWithContentsOfFile:] to manually load the image and store it in the dictionary.
thumbnailCache is NSMutableDictionary declared in header file and it should be initialized in .m init method or equivalent method.
If u have the images in the resources (with jpg format, else change the .jpg to .png in the code), then the line should be like
NSString *thumbnailFile = [NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] resourcePath], fileName];
Instead of using
UIImage *thumbImage = [UIImage imageNamed:#"thumb.png"];
UIImage *thumbImage = [self thumbnailImage:#"thumb.png"];

iPhone/iOS How to load a lot of image in many folder and show in a table view?

I got annoying question...
What if I have many image , and I want load it in to a table view
And show the file name as cell's text , and the preview image is also show in the cell.
When I select the cell , it will push to next view , show the big size image.
That's it .
I don't know how to load many folder to an array?
/*********** EDIT ***********/
This is the folder I set many images inside
You can see that's only one root folder ...
And this is my code to load the image inside
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Image"ofType:#""];
NSDirectoryEnumerator *direnum;
direnum = [fileManager enumeratorAtPath: filePath];
imageFolder = [NSMutableArray new];
for(NSString *filename in direnum){
if([[filename pathExtension] isEqualToString:#"png"]){
[imageFolder addObject:filename];
}
}
NSLog(#"Files in the folder %#",imageFolder);
I got result like this :
Files in the folder (
"macro1.png",
"macro10.png",
"macro11.png",
"macro12.png",
"macro13.png",
"macro14.png",
"macro15.png",
"macro16.png",
"macro17.png",
"macro18.png",
"macro19.png",
"macro2.png",
"macro20.png",
"macro21.png",
"macro22.png",
"macro23.png",
"macro24.png",
"macro25.png",
"macro26.png",
"macro27.png",
"macro4.png",
"macro5.png",
"macro6.png",
"macro7.png",
"macro8.png",
"macro9.png"
)
But what if I change the root folder like this
How to read the image files in the subfolders?
The App won't have issues finding files inside the bundle. The structure of your app development folders is irrelevant to the end product, for the most part. If you are storing the images in the apps bundle, the system can find it.
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"png"]];
When I've had to do this as a quicky solution, I created an NSDictionary entry for each photo and stored that inside of an array in userPrefs. I programmatically created thumbnails for each image to utilize in the cell.imageView.image property, and then used an NSDictionary with #"description", #"imageName", and #"imageNameThumbnail" as the keys. You could do the same thing with an NSArray and just call the objectAtIndex, but I prefer the plain text friendliness of dictionaries.
You can try testing the path information that is being returned. Here are a couple of lines to try:
NSString *path1 = [[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"png"];
NSString *path2 = [[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"png" inDirectory:#"folderName"];
NSLog(#"Path 1: %#",path1);
NSLog(#"Path 2: %#",path2);
See what the output for these lines is, or if they return nothing.
Documents Directory as filePath
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
Then, enumerate the documentsDirectoryPath, and it should read subfolders recursively.
If it is local data you are using, you probably want to put the data in a .plist file. You would just be putting the names of the files in there, and then load the plist into an NSDictionary which you will only have one key for called "images" or something like that. You can then load all the objects under the "images" key into an array and use that array to populate your table.
Hope this makes sense.

Can't read from plist

I have a plist with an array at top level and then a number of items within it.
When I try the following
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"Spots.plist"];
spotsArray = [[NSMutableArray arrayWithContentsOfFile:finalPath] retain];
the array spotsArray is empty.
I have tried a number of things and have used plists successfully before. I dont know what the issue is now.
What could be causing the issue, my plist looks like this
It's not an array at the top level it's a dictionary with a single item called 'New Item'.
Try NSMutableArray *mutableArray = [[[NSDictionary dictionaryWithContentsOfFile:finalPath] objectForKey:#"New Item"] mutableCopy] autorelease]
This should mean that your .plist file does not exist or not readable.
Try to create the file with writeToFile at the same path to verify it works. (It can also help you to verify the directory)