I have this code who write / Create a new image in iOS photo library:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Request to save the image to camera roll
[library writeImageToSavedPhotosAlbum:[imagem CGImage] orientation:(ALAssetOrientation)[imagem imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
//code here...
}
The code that does this, is probably stamped in code writeImageToSavedPhotosAlbum, but in this time I don`t need to create a new image in library, I need to get the Path of the image who exist in the library, In my case the image is inside the variable 'imagem'.
What code I could change the writeImageToSavedPhotosAlbum to get the Path of image?
[EDIT]
I get the image inside the variable imagem in this format:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
UIImage *imagem = [info objectForKey:UIImagePickerControllerOriginalImage];
[imagePicker dismissViewControllerAnimated:YES completion:nil];
}
You have:
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info{
UIImage *imagem = [info objectForKey: UIImagePickerControllerOriginalImage];
}
But you say you don't need the image; you just need the path. That would be:
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSURL *imageurl = [info objectForKey: UIImagePickerControllerReferenceURL];
}
Now you have the URL and you can store it; you can then retrieve the actual image later if you need it.
To get from an asset URL to an image, see my answer here: https://stackoverflow.com/a/22968941/341994
Use ALAssetRepresentation...
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just photos.
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
// Chooses the photo at the last index
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:[group numberOfAssets] - 1] 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];
UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];
Or if you want the path...
NSURL *imageUrl = [representation url];
Related
I am trying to record two videos with UIImagePickerController. Everything is working fine but while recording the second video seems it override the Path of first recorded video.
I need to upload both videos to the server but first video path got nil while uploading and app got crashed. Is there any way to record the second video at different path?
Video Path as follows:
/private/var/mobile/Containers/Data/Application/1465EC90-4B57-41FF-996E-0CCB7713ECE7/tmp/50332801315__A883E4DB-ED72-4D31-9564-22FB363779BD.MOV
/private/var/mobile/Containers/Data/Application/1465EC90-4B57-41FF-996E-0CCB7713ECE7/tmp/50332802324__F11733AD-EB62-426D-BA1C-7E87D2BF66D0.MOV
Here is my imagePicker delegate code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
NSURL *videoUrl = (NSURL*)[info objectForKey:UIImagePickerControllerMediaURL];
NSString *moviePath = [videoUrl path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (moviePath)) {
UISaveVideoAtPathToSavedPhotosAlbum (moviePath, nil, nil, nil);
}
NSLog(#"videoUrl: %#", videoUrl);
NSLog(#"moviePath: %#", moviePath);
// self.moviePath_1 = #"";
// self.moviePath_2 = #"";
NSLog(#"picker.title: %#", picker.title);
if ([picker.title isEqualToString:#"Video_1"]) {
self.moviePath_1 = moviePath;
self.video_1 = YES;
NSLog(#"self.moviePath_1: %#", self.moviePath_1);
self.video_1_Data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:self.moviePath_1]];
NSLog(#"Video_1 Size: %#",[NSByteCountFormatter stringFromByteCount:self.video_1_Data.length countStyle:NSByteCountFormatterCountStyleFile]);
[self setupAndPlayback:#"Video_1"];
} else {
self.moviePath_2 = moviePath;
self.video_2 = YES;
NSLog(#"self.moviePath_2: %#", self.moviePath_2);
self.video_2_Data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:self.moviePath_2]];
NSLog(#"Video_2 Size: %#",[NSByteCountFormatter stringFromByteCount:self.video_2_Data.length countStyle:NSByteCountFormatterCountStyleFile]);
[self setupAndPlayback:#"Video_2"];
}
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Save Video on different Paths. You are overriding the same path that why this issue is happen. Add Time Stamp or increasing Number with Path and save it.
self.moviePath_1 = [NSString stringWithFormat: #"%#-%d.png", moviePath, num] ;
num += 1; // for next time
I use UIImagePickerController to pick image and load to my UIImageView, but I want to save user pick and load it later, I think will be good save absolute path to user defaults but not working (
How I save path // all working
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info
{
[self.backgroundImage setImage:info[UIImagePickerControllerOriginalImage]];
NSURL* localUrl = (NSURL *)[info valueForKey:UIImagePickerControllerReferenceURL];
//in localUrl I see: assets-library://asset/asset.JPG?id=B6C0A21C-07C3-493D-8B44-3BA4C9981C25&ext=JPG
NSUserDefaults *saves = [NSUserDefaults standardUserDefaults];
[saves setValue:[localUrl absoluteString] forKey:#"backimage"];
[saves synchronize];
[self dismissViewControllerAnimated:YES completion:nil];
}
How I try to load: //not working (
NSUserDefaults *saves = [NSUserDefaults standardUserDefaults];
if(![saves objectForKey:#"backimage"]){
[self.backgroundImage setImage:[UIImage imageNamed:#"gameBackiPhone"]];
}else{
NSURL *url = [NSURL URLWithString:[saves objectForKey:#"backimage"]];
//in url I see: assets-library://asset/asset.JPG?id=B6C0A21C-07C3-493D-8B44-3BA4C9981C25&ext=JPG
UIImage *bimage = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:url]];
[self.backgroundImage setImage:bimage];
}
How must be I cannot find.
You can not load image directly using Asset URL, you need to use ALAssetsLibrary class to achieve it. Use following snippet to load image using Asset URL.
// *** It will return Asset from URL passed, create Image from Asset and set into your `UIImageView` ***
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref) {
UIImage *largeimage = [UIImage imageWithCGImage:iref];
yourImageView.image = largeImage;
}
};
// *** If any error occurs while getting image from Asset Library following block will be invoked ***
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(#"Can't get image - %#",[myerror localizedDescription]);
};
// *** Set Asset URL to load Image (assets-library://asset/asset.JPG?id=B6C0A21C-07C3-493D-8B44-3BA4C9981C25&ext=JPG) ***
[NSURL *asseturl = [NSURL URLWithString:yourURL];
// *** Create ALAssetsLibrary Instance and load Image ***
ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
[assetslibrary assetForURL:asseturl
resultBlock:resultblock
failureBlock:failureblock];
Dont forget to import AssetsLibrary framework in your project.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editInfo {
userURL = [editInfo objectForKey:UIImagePickerControllerMediaURL];
userImage = image;
userImageView.image=userImage;
[self dismissViewControllerAnimated:YES completion:nil];}
I then take NSURL userURL, and put it in an UIActivityViewController to use to upload the image. However this never works, and always fails as it's trying to upload (null). However, when I use a preset image included in the xcode project and the following code, it always works and uploads correctly:
NSURL *url = [[NSBundle mainBundle] URLForResource:#"kitten.jpg" withExtension:nil];
If it helps, I'm using https://github.com/goosoftware/GSDropboxActivity
When I use UIImagePickerControllerReferenceURL instead of UIImagePickerControllerMediaURL, I get the following error:
[WARNING] DropboxSDK: File does not exist (/asset.JPG)
Failed to upload assets-library://asset/asset.JPG?id=EECAF4D0-A5ED-40E7-8E6F-3A586C0AB06E&ext=JPG
In theory, UIImagePickerControllerMediaURL is only populated for a movie, not an image. If you use the UIImagePickerControllerReferenceURL then the URL that you're given is not a URL for the file system, but rather the assets library. To get the file from that you'll need to use the asset library. Use something like the following :
typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset){
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref){
UIImage *myImage = [UIImage imageWithCGImage:iref scale:[rep scale] orientation:(UIImageOrientation)[rep orientation]];
// Do whatever you now want with your UIImage
}
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror){
//failed to get image.
};
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:[filePath objectAtIndex:0] resultBlock:resultblock failureBlock:failureblock];
This takes care of the blocks that will handle your request, but you still need to actually request the resource from the assets library. For that, try this :
ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
NSURL myAssetUrl = [NSURL URLWithString:[editInfo objectForKey:UIImagePickerControllerMediaURL]];
[assetslibrary assetForURL:myAssetUrl resultBlock:resultblock failureBlock:failureblock];
And in theory, you should get what you're after :)
The code for this was given by Ramshad and further discussion of it can be found here
Hopefully this will help you with what you're after. Sorry if it's a bit too late :(
Edit
Note that if you're not using ARC, you'll need to tidy up the memory in this example as I haven't included any memory management at all.
I want to get the name of the image picked from the library or newly clicked in -
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
I am using this code:
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
AppDelegate *del = [[UIApplication sharedApplication]delegate];
[self dismissModalViewControllerAnimated:YES];
image = [info objectForKey:UIImagePickerControllerOriginalImage];
NSLog(#"imagekbgfg=====>%#",image);
[self.imageView setImage:image];
imgName = [info objectForKey:UIImagePickerControllerOriginalImage];
del.mainImgName = imgName;
del.imageData = UIImageJPEGRepresentation(image, 1.0);
del.imageApp = image;
}
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])
{
image = [info objectForKey:UIImagePickerControllerOriginalImage];
}
}
How can I do this?
Using the code bellow you will get path like:assets-library://asset/asset.JPG?id=79450962-C0FD-484C-808B-83E045F40972&ext=JPG when your picking image from photo album. This path is valid. It contains the asset ID and asset type.
// Firstly get the picked image's file URL.
NSURL *imageFileURL = [info objectForKey:UIImagePickerControllerReferenceURL];
// Then get the file name.
NSString *imageName = [imageFileURL lastPathComponent];
NSLog(#"image name is %#", imageName);
If you want to get image user picked again using the path you get using UIImagePickerController.(Here maybe you want to save the path so that you can read that image back without asking user to pick that image again) You will need the ALAssetsLibrary otherwise you don't need it.
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
__block UIImage *returnValue = nil;
[library assetForURL:imageFileURL resultBlock:^(ALAsset *asset) {
returnValue = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
} failureBlock:^(NSError *error) {
NSLog(#"error : %#", error);
}];
Take a look at the UIImagePickerControllerDelegate Protocol. The string UIImagePickerControllerReferenceURL contains an URL of your file. You could use it to construct the filename from it.
Other than that there seems to be no built-in way to get the file name from an UIImage or UIImageView object.
Reference:
Stackoverflow answer
You can get the file name using below code:
NSURL *assetURL = [imageDic objectForKey:UIImagePickerControllerReferenceURL];
__block NSString *originalFileName = nil;
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:assetURL resultBlock:^(ALAsset *asset){
originalFileName = [[asset defaultRepresentation] filename];
}
originalFileName give the original file name of resource.
I'm very new to programming, and I jumped right into a project (I know thats not the smartest thing to do, but I'm learning as I go). The app that I'm writing has 10 UIImageViews that display a picture from the users camera roll. The code I'm using needs each of the UIImageViews to have tags. I'm currently using NSData to save the array images, and it works great, but I can't use this method anymore because NSData doesn't support the use of tags. I also can't use NSUserDefaults, because I can't save images to a plist. Here is how I'm attempting to do this (using the NSData method, which works but I have to edit this so that my tags work.)
This is my current code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
if (imageView.image == nil) {
imageView.image = img;
[self.array addObject:imageView.image];
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView2.image == nil) {
imageView2.image = img;
NSLog(#"The image is a %#", imageView);
[self.array addObject:imageView2.image];
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
...
- (void)applicationDidEnterBackground:(UIApplication*)application {
NSLog(#"Image on didenterbackground: %#", imageView);
[self.array addObject:imageView.image];
[self.array addObject:imageView2.image];
[self.user setObject:self.array forKey:#"images"];
[user synchronize];
}
- (void)viewDidLoad
{
self.user = [NSUserDefaults standardUserDefaults];
NSLog(#"It is %#", self.user);
self.array = [[self.user objectForKey:#"images"]mutableCopy];
imageView.image = [[self.array objectAtIndex:0] copy];
imageView2.image = [[self.array objectAtIndex:1] copy];
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:app];
[super viewDidLoad];
}
Any help or suggestions on how to edit this code so that I can save the images, while using tags is much appreciated, thanks!
EDIT: Here is my updated code:
-(IBAction)saveButtonPressed:(id)sender {
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];
for (UIImageView *imageView in self.array) {
NSInteger tag = self.imageView.tag;
UIImage *image = self.imageView.image;
NSString *imageName = [NSString stringWithFormat:#"Image%i.png",tag];
NSString *imagePath = [docsDir stringByAppendingPathComponent:imageName];
[UIImagePNGRepresentation(image) writeToFile:imagePath atomically:YES];
}
NSLog(#"Saved Button Pressed");
}
- (void)applicationDidEnterBackground:(UIApplication*)application {
}
-(void)viewDidLoad {
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0];
NSArray *docFiles = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:docsDir error:NULL];
for (NSString *fileName in docFiles) {
if ([fileName hasSuffix:#".png"]) {
NSString *fullPath = [docsDir stringByAppendingPathComponent:fileName];
UIImage *loadedImage = [UIImage imageWithContentsOfFile:fullPath];
if (!imageView.image) {
imageView.image = loadedImage;
} else {
imageView2.image = loadedImage;
}
}
}
}
You need to use "Fast Enumeration" to parse the array's objects, and write each object to disk sequentially. First, you're going to need to add the UIImageView objects to the array instead of the UIImage property of the UIImageView, so you can recover the tag. So instead of writing
[self.array addObject:imageView.image];
It will be
[self.array addObject:imageView];
Try to follow along with my code. I inserted comments on each line to help.
-(void)applicationDidEnterBackground:(UIApplication *)application {
//Obtain the documents directory
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainmask,YES) objectAtIndex:0];
//begin fast enumeration
//this is special to ObjC: it will iterate over any array one object at a time
//it's easier than using for (i=0;i<array.count;i++)
for (UIImageView *imageView in self.array) {
//get the imageView's tag to append to the filename
NSInteger tag = imageView.tag;
//get the image from the imageView;
UIImage *image = imageView.image;
//create a filename, in this case "ImageTAGNUM.png"
NSString *imageName = [NSString stringWithFormat:#"Image%i.png",tag];
//concatenate the docsDirectory and the filename
NSString *imagePath = [docsDir stringByAppendingPathComponent:imageName];
[UIImagePNGRepresentation(image) writeToFile:imagePath atomically:YES];
}
}
To load the images from disk, you'll have to look at your viewDidLoad method
-(void)viewDidLoad {
//get the contents of the docs directory
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainmask,YES) objectAtIndex:0];
//Get the list of files from the file manager
NSArray *docFiles = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:docsDir error:NULL]);
//use fast enumeration to iterate the list of files searching for .png extensions and load those
for (NSString *fileName in docFiles) {
//check to see if the file is a .png file
if ([fileName hasSuffix:#".png"]) {
NSString *fullPath = [docsDir stringByAppendingPathComponent:fileName];
UIImage *loadedImage = [UIImage imageWithContentsOfFile:fullPath];
//you'll have to sort out how to put these images in their proper place
if (!imageView1.image) {
imageView1.image = loadedImage;
} else {
imageView2.image = loadedImage;
}
}
}
}
Hope this helps
One thing you need to be aware of is that when an app enters the background it has about 5 seconds to clean up its act before it's suspended. The UIPNGRepresentation() function takes a significant amount of time and is not instantaneous. You should be aware of this. It would probably be better to write some of this code in other places and do it earlier than at app backgrounding. FWIW
You can use the [NSbundle Mainbundel] to store that images.
To get path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
First, there's still a problem in your for loop.
for (UIImageView *imageView in self.array) {
NSInteger tag = self.imageView.tag;
UIImage *image = self.imageView.image;
// ...
}
Before you make any other changes, you must understand why. imageView is your for loop control variable, which changes on each iteration through the loop. self.imageView is a different thing. It is the first of the 10 imageViews attached to your viewController. Every time this loop cycles, it looks at the first imageView, and only the first.
As for why saving doesn't work, it's probably because the arrays elsewhere aren't working. Add some logging to make sure there's something in the array, and that it has as many elements as you expect.
-(IBAction)saveButtonPressed:(id)sender {
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];
// Log to make sure the views expected have previously been stored.
// If the array is empty, or shorter than expected, the problem is elsewhere.
NSLog(#"Image view array before saving = %#", self.array);
for (UIImageView *imageViewToSave in self.array) {
NSInteger tag = imageViewToSave.tag;
UIImage *image = imageViewToSave.image;
NSString *imageName = [NSString stringWithFormat:#"Image%i.png",tag];
NSString *imagePath = [docsDir stringByAppendingPathComponent:imageName];
// Log the image and path being saved. If either of these are nil, nothing will be written.
NSLog(#"Saving %# to %#", image, imagePath);
[UIImagePNGRepresentation(image) writeToFile:imagePath atomically:NO];
}
NSLog(#"Save Button Pressed");
}