iPhone store image from imageview to file - iphone

In my iPhone App I am picking image from iPhone Image Library as well from device camera,
and I am displaying that image in imageView.
I am able to store my image into iPhone image Library.
But now I want to store my image in some Directory with specific name, so I can use that image again in my application and also I want to store it in sqlite file.

There is a short writeup of this here: http://iosdevelopertips.com/data-file-management/save-uiimage-object-as-a-png-or-jpeg-file.html
Here is the relevant code stolen directly from that site:
// Create paths to output images
NSString *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Test.png"];
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Test.jpg"];
// Write a UIImage to JPEG with minimum compression (best quality)
// The value 'image' must be a UIImage object
// The value '1.0' represents image compression quality as value from 0.0 to 1.0
[UIImageJPEGRepresentation(image, 1.0) writeToFile:jpgPath atomically:YES];
// Write image to PNG
[UIImagePNGRepresentation(image) writeToFile:pngPath atomically:YES];
To store it in a SQLite Database you would take the code that makes an NSData object (either UIImageJPEGRepresentation or UIImagePNGRepresentation) and save them to a BLOB column.

NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/ImageFileName.jpg"];
[UIImageJPEGRepresentation(yourUIImageView.image,1.0) writeToFile:path atomically:YES];
Documentation: UIImageJPEGRepresentation
If you're handling PNGs there's another method called UIImagePNGRepresentation.

Related

NSCoding, NSData, UIImages and performance

I'm using NSCoding to manage a custom object with a few different fields, one of them images. I'm only targeting iOS 5.0+ and have switched to ARC. I have everything working but am focused on performance--I haven't seen a question like this asked, so here it goes:
I transform the UIImage into NSData and add it to the main NSCoding file (a plist, if it matters) for storage on the disk. If there is more than one image, the image names become sequential (e.g. image1, image2, image3.) I then use the image both in a UITableView (as a resized thumbnail) and in a detail view. The negative side to this is that the plist balloons in size, which means slow initial load times when I use it because it's loading all of the NSData at once.
What is the best way to eliminate this problem and only force the loading of one image at a time?
What I've thought of:
I write the NSData to the disk, add an array to the plist, and add only a reference to the filename of each image to the array. I suppose I'd then reference the image filename at specified position, find it on the disk, and use it?
Any and all thoughts would be most welcome. I'm more stuck on the conceptual implementation than anything else and, funnily enough, this is not an oft-discussed topic.
Thanks,
EDIT:
As requested below, here's an example of taking an image and turning it into NSData:
UIImage *originalImage;
NSData *imageData = UIImagePNGRepresentation(originalImage);
//I save it all to the app's document directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//I am using the images in a tableView and thus found it easiest to append the row number to each image filename.
//'y' below is just an integer that corresponds to the number of items in the master array
NSString *fileName = [NSString stringWithFormat:#"image%d.png",y];
documentsDirectory = [documentsDirectory stringByAppendingPathComponent:fileName];
[imageData writeToFile:documentsDirectory atomically:YES];
// NSLog(#"The filename is %#", fileName);
//newObject is an instance of my NSCoding object
[newObject setImageName: fileName];
Your suggestion is sound. Imagine a relational database. I would never save the images in one field as a blob. A filesystem is a very good place to save binary date in large amounts. It also gives you easy ways to duplicate files and so on.
So saving a reference in your plist will make parsing really fast and lazy loading an easy task to process images only when you need them.
iOS Programming: The Big Nerd Ranch Guide has a perfect example of this solution in chapter 14 of the 3rd Edition. Just download the code that is accessible from their site for a completed solution.
iOS Programming 3rd edition
Download Solutions

How to save Images Quickly

I'm doing video conversion using ffmpeg. I'm getting the sequence of images. Now I am using
[UIImagePNGRepresentation(video.currentImage) writeToFile:fileName atomically:YES];
...to save the file into a directory. But this taking lots of time to save. I need to save this image quickly.
Try With UIImageJPEGRepresentation ( UIImage *image, CGFloat compressionQuality)

How to Convert data obtained from Sqlite database into NSArray to NSData in iPhone SDK

In My iPhone App,
I am converting my image in to NSData format and storing it into sqlite database Table in dataType="BLOB",
But, I am retriving that image (stored in NSData format) into NSArray Format from database,
The Problem is I am not able to convert NSArray to NSData ( Which would Help me to get my image back into NSData format )
Please Help and Suggest,
Thanks
Your requirement is so odd.
you can store image in local file system with the file name in sqlite
if you really want images store in sqlite, you can every image in sqlite separately rather than archive images in NSArray than convert to NSData
Use NSKeyedArchiver How to convert NSArray to NSData?
UIImage *imgData = [UIImage imageWithData:[yourArray objectAtIndex:theIndex]];
for multiple images in one array you can loop it
like
for (int i = 0;i<[yourArray count];i++) {
UIImage *img = [UIImage imageWithData:[yourArray objectAtIndex:i];
//do something here with each image
// for example, add it to an ImageView
}
P.S. if theres only one image, its index is 0
hope this helps

displaying an image from sqlite table

I was storing an image in a sqlite table as blob data and displaying it using the following code:
self.myImage.image = [[[UIImage alloc] initWithData:recipe.image] autorelease];
I'm now using the image file name in the sqlite fields instead and storing the image on the filesystem. what would the code be to display it that way? I'm having a hard time figuring it out.
normally to display an image from the filesystem I'd use:
UIImage *image = [UIImage imageNamed:#"something.png"];
in this case I have to grab the string that's in the table field/attribute.
thanks in advance.
You can load UIImage with absolute filepath by following API.
+ (UIImage *)imageWithContentsOfFile:(NSString *)path;
+(UIImage *)imageNamed:(NSString *)name will look for an image from application's main bundle. In other word, it will look for an image from Resources.
Editted:
You said that you stored the image on the filesystem. So, I think you can retrive the absolute filepath of image from sqlite database, doesn't it?
NSString *imgPath;
/// get imgPath from sqlite database
...
/// get the image by filepath
self.myImage.image = [UIImage imageWithContentOfFile:imgPath];
And, my question is how do you store the image on the filesystem.

Save Image to sandbox from UIImage in iPhone

I am showing very big size images in UITableView, because of this my app is getting crashed after some time. Now i want to resize the image and save it to disk. can some one help me resizing the image from NSData/UIImage and saving saving it to the disk.
I got the code to resize the image from UIImage, so as the result i have my resized in image in UIImage object, how to save it to iphone sandbox.
Thanks,
Here is code to save to the Documents directory on iOS that is from working code.
// Convert UIImage to JPEG
NSData *imgData = UIImageJPEGRepresentation(image, 1); // 1 is compression quality
// Identify the home directory and file name
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Test.jpg"];
// Write the file. Choose YES atomically to enforce an all or none write. Use the NO flag if partially written files are okay which can occur in cases of corruption
[imgData writeToFile:jpgPath atomically:YES];
You're asking 'how do I write a file' right?
I guess there is a touch of complication in that you probably want to write into the Library/Caches directory, so when the phone gets backed up you don't save those files.
Get the root of the app folder w/ NSHomeDirectory() and then append Library/Caches.
You can write an NSData to the fs w/ a method on NSData. If you have a UIImage, you can do UIImageJPEGRepresentation() or UIImagePNGRepresentation to get data.
NSData *imgData = UIImageJPEGRepresentation(image, 1);
CGImageSourceRef source = CGImageSourceCreateWithData((CFMutableDataRef)imgData, NULL);
NSDictionary *metadata = [(NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source,0,NULL)autorelease];
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Test.jpg"];
[imageMutableData writeToFile:jpgPath atomically:YES];
It will copy your image to documents folder in sandbox with name Test.jpg.
If you want to do it for PNG you can try UIImagePNGRepresentation(image);