11

I am using ELCImagePickerController in my app and I don't want to save the selected fullScreenImage to my array because if i selected 40 iPad images then that is not good.

I want to get data from UIImagePickerControllerReferenceURL instead of UIImagePickerControllerOriginalImage from the dict of method - (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info.

I have tried:

NSDictionary *dict = [info objectAtIndex:count];            

NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",[dict objectForKey:@"UIImagePickerControllerReferenceURL"]]]];//UIImagePNGRepresentation([UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@",[dict objectForKey:@"UIImagePickerControllerReferenceURL"]]] );
        NSLog(@"length %d",[data length]);
        imageview.image = [UIImage imageWithData:data];

However, every time I am getting 0 bytes. I have tried with all the answers available in forum but no use.

Can anyone answer this please?

Jessedc
  • 12,320
  • 3
  • 50
  • 63
Steve Gear
  • 757
  • 2
  • 16
  • 44

3 Answers3

26

UIImagePickerControllerReferenceURL returns NSURL object not the string object. Please change your code to -

NSData *data = [NSData dataWithContentsOfURL:[dict objectForKey:@"UIImagePickerControllerReferenceURL"]];
NSLog(@"length %d",[data length]);
imageview.image = [UIImage imageWithData:data];

UIImagePickerControllerReferenceURL returns NSURL object for Assets Library, so you can get image as -

ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
[assetLibrary assetForURL:[[self.imagedata objectAtIndex:i] valueForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) {
    ALAssetRepresentation *rep = [asset defaultRepresentation];
    Byte *buffer = (Byte*)malloc(rep.size);
    NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
    NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];//this is NSData may be what you want
    [data writeToFile:photoFile atomically:YES];//you can save image later
} failureBlock:^(NSError *err) {
    NSLog(@"Error: %@",[err localizedDescription]);
}];

Note: ALAssetsLibrary is deprecated in iOS 9.

saadnib
  • 11,145
  • 2
  • 33
  • 54
  • thanks for your reply...i tried like that also even though in my log i am getting length as 0 "2012-05-29 18:32:13.536 myapp[1793:707] length 0" – Steve Gear May 29 '12 at 13:03
  • 1
    it is 0 because UIImagePickerControllerReferenceURL return NSURL object for Assets Library. so you need to use Assets Library to get image from this url. As - NSURL *referenceURL = [info objectForKey:UIImagePickerControllerReferenceURL]; ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; [library assetForURL:referenceURL resultBlock:^(ALAsset *asset) { ... } failureBlock:^(NSError *error) { ... }]; – saadnib May 29 '12 at 13:27
  • For what it's worth ALAssetsLibrary is deprecated in iOS 9. I have added an additional answer below. – Jessedc Jul 20 '16 at 08:21
  • @Jessedc, thanks for notification, i added a note for deprecation in my answer. – saadnib Jul 20 '16 at 09:33
10

This question ranks well on Google for UIImagePickerControllerReferenceURL so I thought I'd add the correct way to use UIImagePickerControllerReferenceURL in iOS9 and later as ALAssetLibrary has been deprecated in favour of the Photos Framework.

The correct way to access the photo using UIImagePickerControllerReferenceURL provided in the info dictionary from imagePickerController(_:didFinishPickingMediaWithInfo:) is via Photos Kit PHAsset.

A basic implementation of UIImagePickerControllerDelegate utilising Photos Framework to fetch the UIImage would look something like this:

class YourViewController: UIViewController, UIImagePickerControllerDelegate
{
    public func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]?) {
        guard let info = info, let url = info[UIImagePickerControllerReferenceURL] as? NSURL else {
            // Using sourceType .Camea will end up in here as there is no UIImagePickerControllerReferenceURL
            picker.dismissViewControllerAnimated(true) {}
            return
        }

        let fetchResult = PHAsset.fetchAssetsWithALAssetURLs([url], options: nil)
        if let photo = fetchResult.firstObject as? PHAsset {
            PHImageManager.defaultManager().requestImageForAsset(photo, targetSize: PHImageManagerMaximumSize, contentMode: .AspectFill, options: nil) {
                image, info in
                // At this point you have a UIImage instance as image
            }
        }
    }
}

The code above will not process callbacks when sourceType is .Camera since as the info dictionary does not contain UIImagePickerControllerReferenceURL.

Jessedc
  • 12,320
  • 3
  • 50
  • 63
  • Note `UIImagePickerControllerReferenceURL` is deprecated in iOS 11.0 too, so one might use condition `NSString *infoKey; if (@available(iOS 11, *)) { infoKey = UIImagePickerControllerPHAsset; } else { infoKey = UIImagePickerControllerReferenceURL; }` – schmidt9 Nov 23 '18 at 11:00
  • PHAsset.fetchAssetsWithALAssetURLs is now deprecated as well. – Martin-Gilles Lavoie Sep 12 '19 at 17:42
1

in ELCImagePickers "Selected assets" you can do

-(void)selectedAssets:(NSArray*)_assets {

"... your code .?.?."

    NSMutableArray *returnArray = [[NSMutableArray alloc] init];

    for(ALAsset *asset in _assets) {

        NSMutableDictionary *workingDictionary = [[NSMutableDictionary alloc] init];
        [workingDictionary setObject:[[asset valueForProperty:ALAssetPropertyURLs] valueForKey:[[[asset valueForProperty:ALAssetPropertyURLs] allKeys] objectAtIndex:0]] forKey:@"UIImagePickerControllerReferenceURL"];

".. any other properties you need ?"

        [returnArray addObject:workingDictionary];

    }
}

Then in your other class to save from array

- (void) importImagesFromArray:(NSArray *)_images toFolder:(NSString *)folderPath
{
   if ([_images count] > 0) {

    //... YOUR CODE HERE FOR CHECKING YOUR ARRAY...Maybe a loop or something//
    //
    //
    //

    //ex:

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    for (NSDictionary *dict in _images) {



        [library assetForURL:[dict objectForKey:@"UIImagePickerControllerReferenceURL"]
                 resultBlock:^(ALAsset *asset){

                     //You Can Use This

                     UIImage *theImage = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]
                                                             scale:1.0
                                                       orientation:[[asset valueForProperty:@"ALAssetPropertyOrientation"] intValue]];

                     //[....save image blah blah blah...];

                     ///////////////////////////////////////////////////
                     ///////////////////////////////////////////////////

                     ////// OR YOU CAN USE THIS////////////////////

                     ALAssetRepresentation *rep = [asset defaultRepresentation];
                     Byte *buffer = (Byte*)malloc(rep.size);
                     NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
                     NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];//this is NSData may be what you want
                     [data writeToFile:[folderPath stringByAppendingPathComponent:@"Some Filename You Need To Assign"] atomically:YES];


                 }

                failureBlock:^(NSError *error){
                    NSLog(@"Error saving image");

                }];

        // Dont forget to release library

    }
}
}
mrburns05
  • 189
  • 1
  • 7