I'm interested in uploading a file (image) from an iPhone library/camera roll to a remote web server. I already have a script working that will upload any file from the phone to a web server. However, I assume that to upload an image from the iPhone, I need the PATH to said image. Is there any way this can be done, once the user picks said image from the camera roll? I.e., how do I get the file path of an image selected in the camera roll?
I have tried to no avail.
Thanks!
You will want to look at the ALAssetsLibrary functions - these let you access photos and videos that are stored in your Photos and Videos libraries on your iOS device.
Specifically, something like:
ALAssetsLibrary *assets = [[ALAssetsLibrary alloc] init];
[assets enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop) {
//the ALAsset should be one of your photos - stick it in an array and after this runs, use it however you need
}
}
failureBlock:^(NSError *error) {
//something went wrong, you can't access the photo gallery
}
];
EDIT
If you are using the UIImagePickerController rather than a purely programatical approach, this simplifies it greatly:
In:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *img = [info objectForKey:UIImagePickerControllerEditedImage];
//you can use UIImagePickerControllerOriginalImage for the original image
//Now, save the image to your apps temp folder,
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:#"upload-image.tmp"];
NSData *imageData = UIImagePNGRepresentation(img);
//you can also use UIImageJPEGRepresentation(img,1); for jpegs
[imageData writeToFile:path atomically:YES];
//now call your method
[someClass uploadMyImageToTheWebFromPath:path];
}
Related
I stored videos in my document directory from photo library. Now i want to show all videos which are stored in my document directory.. but i don't know how its possible???
Actually i want to display all videos as like its open in photo library(four videos in a single row).. and when i click on any video... the video is start playing...
can anybody help me which is the best way to show all videos from document directory to ViewController....
Thanx......
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSURL * movieURL = [info valueForKey:UIImagePickerControllerMediaURL] ;
NSData * movieData = [NSData dataWithContentsOfURL:movieURL];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[[self imageNameTextField]text]];
fullPath = [fullPath stringByAppendingFormat:#".MOV"];
[ movieData writeToFile:fullPath atomically:YES];
}
I recommend you to use an open-source grid-view control. You can find them in GitHub. For instance, BDDynamicGridViewController is interesting. But it is not the only option. There is also AQGridView.
Also, there is a popular open-source library, called Three20 and it has it's upgrade, called Nimbus. This library has a custom control for displaying photos grid. You can use the same for displaying video thumbnails grid. For instance, try this.
After you will manage to use or create Grid view control, you will need thumbnail generator for the videos. Use this topic for that purpose.
To get access to the videos stored in the photo library on the device you need to use the Asset library. The following code shows you how to get access to the first video in the photo library :
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just videos.
[group setAssetsFilter:[ALAssetsFilter allVideos]];
// For this example, we're only interested in the first item.
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:0] options:0
usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
NSURL *url = [representation url];
AVAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
// Now you have the AV asset for the video.
}
}];
}
failureBlock: ^(NSError *error) {
// Typically you should handle an error more gracefully than this.
NSLog(#"No groups");
}];
[library release];
This example is in the AVFoundation Programming guide, more details on the Apple developer website
I have made the same project for one of my client. I can tell you the idea but cann't tell you the code. The idea is while taking or saving video take the starting frame of every video and save it as PNG image as icon of the video. By this way you will get the icon of every video. Save all the Images in different folder in such a manner that each image can be link with its video. Now retrieve all videos from the document folder by below code
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
filelist = [filemgr contentsOfDirectoryAtPath:path error:nil];
*filelist is the NSArray
In the same manner retrieve the icons of the videos.
Make a grid view of buttons. Set images of the buttons as icons of the videos. Show the video names. When click on the video open a new view controller and make a video player ther play the video there.
I'm trying to save Images the user takes with the camera
1) If I use the UIImageWriteToSavedPhotosAlbum I can't seem to assign the fileName that I want. How, can you choose the file name?
The nice thing about using this option is
[picker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
Then gives a thumbnail gallery of Photo Library directory.
2) which leads me to my next question Can
[picker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; be used to get images from your own personal directory ?
3) Is there anyway to programmatically create sub folders within the Photo Library
4) Lastly,
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSPicturesDirectory, NSUserDomainMask, YES);
if (![[NSFileManager defaultManager] fileExistsAtPath:[paths objectAtIndex:0] isDirectory:&isDir]) {
NSError *error;
[[NSFileManager defaultManager] createDirectoryAtPath:[paths objectAtIndex:0 withIntermediateDirectories:YES attributes:nil error:&error];
}
Checking to see if the NSPicturesDirectory exists so I can write to it
I keep getting a Cocoa error 513 not permitted
Thanks in advance
You can't assign a file name to photo library images. ios assign a file name called asset url to the images that are saved to the photo library, we can't change that.
If you need to save the images to photo library you can use ALAssetsLibrary
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation) [image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error)
{
// Eror
}
else
{
// Success
}
}];
[library release];
For more information check:
How to save picture to iPhone photo library?
Save image in UIImageView to iPad Photos Library
1.)
To save a filename of your choice, you need to save the image to your documents directory. This can easily be done like so:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
NSString *current = [NSString stringWithFormat:#"%#/%#",PHOTODATA_PATH,currentItem];
UIGraphicsBeginImageContext(CGSizeMake(160,160));
[image drawInRect:CGRectMake(0,0,160,160)];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * thumbSize = UIImageJPEGRepresentation(scaledImage, 1.0);
[thumbSize writeToFile:[NSString stringWithFormat:#"%#_thumb.jpg",current] atomically:YES];
NSData * fullSize = UIImageJPEGRepresentation(image, 1.0);
[fullSize writeToFile:[NSString stringWithFormat:#"%#.jpg",current] atomically:YES];
[self dismissModalViewControllerAnimated:YES];
}
Of course this code may need to be edited to fit your exact situation but gives the basic understanding and way to save a photo to file using NSData.
2.)
Yes, UIImagePickerControllerSourceTypePhotoLibrary will access your Photo Library on your device. Any photos saved or taken from the camera roll will be accessible using this.
3.)
No, you cannot create subfolders in the Photo Library using your application. This can be done using iPhoto or iTunes or the like.
4.)
You only have access to the Documents and Library paths contained within your sandboxed environment. The only way you can save a photo to the Photo Library is by using the appropriate public methods. There is no need to check if the directory exists, the OS will take care of all of the "behind the scenes" tasks it needs to in order to manage the Photo Library.
In my app I am taking a picture and showing it in an image view.
Now I need the path of that image so I can upload it to a server.
How do I get that path? I try importing ALAsset framework but there is no framework called that my x code (4.2) iOS 5.0
NSData *data = UIImagePNGRepresentation(imagePic.image);
NSString *file = [NSTemporaryDirectory() stringByAppendingPathComponent:#"upload.jpg"];
[data writeToFile:file atomically:YES];
[[EPUploader alloc] initWithURL:[NSURL URLWithString:#"myWebSite"]
filePath:#"file"
delegate:self
doneSelector:#selector(onUploadDone:)
errorSelector:#selector(onUploadError:)];
This is what I am currently trying.
Also what would be a hard coded path to a photo in an iphone camera roll? "iphone/pictures/myPic" ?? so I can try the upload separate from finding the path.
Please and Thank you
EDIT:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Access the uncropped image from info dictionary
image2 = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
// Save image
UIImageWriteToSavedPhotosAlbum(image2, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
imagePic.image = image2;
[picker release];
}
An image view has no path, it's in memory. You'll have to save the path you get when you return from taking the image. In the delegate method imagePickerController:didFinishPickingMediaWithInfo: you can get the NSURL in UIImagePickerControllerMediaURL which points to the image on disk:
NSURL *imageURL = [info valueForKey:UIImagePickerControllerMediaURL];
What I am needing to do is, take a picture or choose one form the photo library, then save it within the app so that it isn't visible anywhere else but within the app. For example it would be like "My Secret Folder" where images are only seen within the app. I am not making a secret folder app.... So don't worry... =)
I am sorry I don't have much code to show, but I have no idea how to do this.
I was looking at the Rich Text File and was wondering if that was the way to go and if it can even store images, or if I have to do it a different way.
Thanks,
Denali Creative LLC
P.S.
What I am looking to do is save MORE THAN ONE image within the application. So i will need to be able to name what the Image or what ever the image is saved into's file name.
Lookup/Search code for using UIImagePickerController
Convert Image to Data using Convert Image to Data
Save the data to the document folder. No other apps can access your documents folder.
folder, see this post Save Image to Disk
Read data from disk, convert to image and display to reverse process.
You can save the images within your application's Sandbox
The Documents folder is backup during syncs, and Library/Caches folder is not. That gives you a choice between levels of secrecy.
Once you have your image (UIImagePickerController and a class that follows <UIImagePickerControllerDelegate> protocol), convert it to NSData and archive it to your desired folder.
Something like
NSData * imageData = UIImagePNGRepresentation (image);
NSData * imageData = UIImageJPEGRepresentation (image);
when you unarchive the NSData, you can create the image with
[UIImage imageWithData:data];
So u dont want other app to recognize ur images. I am not sure but this might help you. Instead of standard png or jpg extention, just replace a dummy extention like .abc which other apps cant recognize. There might be other ways but I was using this method.
Extract your image from the PhotoPicker info dictionary in the photo picker delegate callback.
Set up a subdirectory somewhere under your /Documents folder, and write the image there.
NSData *pngData = UIImagePNGRepresentation(_myUIImage);
BOOL successFlag = [pngData writeToFile:documentDirectorySubFolder options:0x0 error:&error];
use UIImagePickerController class and implement it delegate
There is a delegate method of image picker view delegate
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info ;
This method is get called when you select the picture from photo Library or take picture from camera.That is good to save your images in core data base then it is only visible with in your app.
I think this idea may be help for you. You can create one app for that like with SQLIte. in which you save your images within your app. but the problem is the images which you save in your app and keep safe from others, you have to manually remove from image gallery
I recommend that you store the images in the Documents Directory and read them from there as it is the most appropriate location to store app content.
Save Image to Documents Directory
-(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];
} else {
NSLog(#"Image Save Failed\nExtension: (%#) is not recognized, use (PNG/JPG)", extension);
}
}
Load Image From Documents Directory
-(UIImage *)loadImage:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/%#.%#", directoryPath, fileName, extension]];
return result;
}
How-To
//Definitions
NSString * documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
//Save Image to Directory
[self saveImage:imageFromURL withFileName:#"My Image" ofType:#"png" inDirectory:documentsDirectoryPath];
//Load Image From Directory
UIImage * imageFromWeb = [self loadImage:#"My Image" ofType:#"png" inDirectory:documentsDirectoryPath];
I have an application, in which the user will select an image from a UIImagePickerView.
After selecting an image from it, I want to save it in my application.
How can this be achieved?
Thanks in advance for helping me.
Assuming you're using SDK 3.0, here is some code to save the image into your application's documents folder:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Dismiss the picker
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
// Get the image from the result
UIImage* image = [info valueForKey:#"UIImagePickerControllerOriginalImage"];
// Get the data for the image as a PNG
NSData* imageData = UIImagePNGRepresentation(image);
// Give a name to the file
NSString* imageName = "MyImage.png";
// Now, we have to find the documents directory so we can save it
// Note that you might want to save it elsewhere, like the cache directory,
// or something similar.
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];
// and then we write it out
[imageData writeToFile:fullPathToFile atomically:NO];
return;
}
I would say something like this:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
self.resumePreviousSettingAfterEditing = true;
[self.topImageView setImage:image];
[cubeModel setImage:image forFace:[cubeModel.validFaces objectAtIndex:selectedRowInFacePicker]];
[self dismissImagePickerAnimated:true];
}
You register an event in your controller to handle the image selection. In that event handler, call a method somewhere, say in your model to set the new image. That function would look something like this:
(void)saveImage:(UIImage *)image withName:(NSString *)imageName {
// get the image path
NSString *filename = [self determineImagePath:imageName];
// make sure the file is removed if it exists
NSFileManager *fileManager = [NSFileManager defaultManager];
if([fileManager fileExistsAtPath:filename]) {
if(NO == [fileManager removeItemAtPath:filename error:NULL]) {
}
}
// Now, save the image to a file.
if(NO == [UIImagePNGRepresentation(image) writeToFile:filename atomically:YES]) {
[NSException raise:#"Image Save Failed" format:#"Unable to store image %s", filename];
}
}
When you want to load the image again, you would so something like:
- (UIImage *)loadImage:(NSString *)imageName {
NSString *filename = [self determineImagePath:imageName];
NSFileManager *fileManager = [NSFileManager defaultManager];
self.currentImage = nil;
if([fileManager fileExistsAtPath:filename]) {
NSData *imageData = [[NSData alloc] initWithContentsOfFile:filename];
UIImage *image = [UIImage imageWithData:imageData];
self.currentImage = image;
}
return self.currentImage;
}
And don't get me started on transforming which is way harder than it should be.
Enjoy,
Jacob
One thing you will need to address when saving images returned by UIImagePickerVIewController is that writing the data to disk will almost always be unacceptably slow. Your UI will hang while the writing is occurring. So, you should always execute these types of operations in an asynchronous queue. Even if the performance seems good enough for your application when testing, you should still do it an asynch queue -- you never know what other processes the device might have going on which might slow the save down once your app is in the hands of users.
Newer versions of iOS make saving photos asynchronously really, really easy using Grand Central Dispatch (GCD). The steps are:
Create an NSBlockOperation which saves the image
In the block operation's completion block, read the image from disk & display it (the only caveat here is that you must use the main queue to display the image: all UI operations must occur on the main thread).
Add the block operation to an operation queue and watch it go!
That's it. And here's the code:
// Grab the image
UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
// Create a block operation with our saves
NSBlockOperation* saveOp = [NSBlockOperation blockOperationWithBlock: ^{
[UIImagePNGRepresentation(image) writeToFile:file atomically:YES];
}];
// Use the completion block to update our UI from the main queue
[saveOp setCompletionBlock:^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
UIImage *image = [UIImage imageWithContentsOfFile:file];
// TODO: Assign image to imageview
}];
}];
// Kick off the operation, sit back, and relax. Go answer some stackoverflow
// questions or something.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:saveOp];
Once you are comfortable with this code pattern, you will find yourself using it a lot. It's incredibly useful when generating large datasets, long operations on load, etc. Essentially, any operation that makes your UI laggy in the least is a good candidate for this code. Just remember, you can't do anything to the UI while you aren't in the main queue and everything else is cake.