Getting a URL from (to) a “picked” image, iOS

2019-08-01 15:38发布

With this code below, I can extract metadata from an image (pre-added to my project), and render the info as text. This is exactly what I want to do. The SYMetadata is created by pointing to an image via URL. initWithAbsolutePathURL. I want to do the same thing with a UIImage or maybe the image that is being loaded to the UIImage. How do I get the URL to the image that the picker selects? Or how do I create an "asset" from this incoming image?

The documentation describes initWithAsset. Have not figured out how to use it yet though, or if this is the right way to go for my purpose. Any help greatly appreciated.

NSURL *imageURL = [[NSBundle mainBundle] URLForResource:@"someImage" withExtension:@"jpg"];
SYMetadata *metadata = [[SYMetadata alloc] initWithAbsolutePathURL:imageURL];
[textView setText:[[metadata allMetadatas] description]];

Note: I tried adding an NSURL like this imageURL = [info valueForKey:@"UIImagePickerControllerReferenceURL"];, in the "pickerDidFinish" method but the metadata is null after I add this URL to the above code.

2条回答
等我变得足够好
2楼-- · 2019-08-01 15:47

If you've an ALAsset (in my sample _detailItem), you can have metadata in this way:

NSDictionary *myMetadata = [[_detailItem defaultRepresentation] metadata];
查看更多
劫难
3楼-- · 2019-08-01 15:53

If you are using the imagePickerController, the delegate method will give you what you need

- (void) imagePickerController:(UIImagePickerController *)picker
 didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    if ([[info allKeys] containsObject:UIImagePickerControllerReferenceURL]){
        // you will get this key if your image comes from a library
        [self setMetaDataFromAssetLibrary:info];
    } else if ([[info allKeys] containsObject:UIImagePickerControllerMediaMetadata]){
        // if the image comes from the camera you get the metadata in it's own key
        self.rawMetaData = [self metaDataFromCamera:info];
    }
}

From Asset Library - bear in mind that it takes time to complete and has an asynchronous completion block, so you might want to add a completion flag to ensure you don't access the property before it has been updated.

- (void) setMetaDataFromAssetLibrary:(NSDictionary*)info
{
    NSURL *assetURL = [info objectForKey:UIImagePickerControllerReferenceURL];

    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    [library assetForURL:assetURL
             resultBlock:^(ALAsset *asset)  {
                 self.rawMetaData = asset.defaultRepresentation.metadata;
             }
            failureBlock:^(NSError *error) {
                NSLog (@"error %@",error);
            }];
}

From Camera:

    - (NSDictionary*)metaDataFromCamera:(NSDictionary*)info
   {
        NSMutableDictionary *imageMetadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
       return imageMetadata;
   }

Here is how to get metadata from a UIImage

  - (NSDictionary*)metaDataFromImage:(UIImage*)image
   {
        NSData *jpegData = [NSData dataWithData:UIImageJPEGRepresentation(image, 1.0)];
        return [self metaDataFromData:jpegData];
    }

But take care - a UIImage can already stripped of much of the metadata from the original.. you will be better off getting the metadata from the NSData that was used to create the UIImage...

    - (NSDictionary*)metaDataFromData:(NSData*)data
{
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    CFDictionaryRef imageMetaData = CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
    return (__bridge NSDictionary *)(imageMetaData);
}
查看更多
登录 后发表回答