Tuesday, May 23, 2017

Get base64 photo from iOS photo library uri

Leave a Comment

I'm building an app in React Native, and I need to get an image from the Photo Library as base64 using the photo uri (e.g. photos://A2B9B28B-9A3E-4190-BCA0-B11F1E587085/L0/002). I was originally using the Asset Library but I've updated my app to use the new Photo Library and I'm struggling to get it to work.

My old Asset Library method was:

{   NSURL *url = [[NSURL alloc] initWithString:input];   ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];   [library assetForURL:url resultBlock:^(ALAsset *asset) {     ALAssetRepresentation *rep = [asset defaultRepresentation];     CGImageRef imageRef = [rep fullScreenImage];     NSData *imageData = UIImagePNGRepresentation([UIImage imageWithCGImage:imageRef]);     NSString *base64Encoded = [imageData base64EncodedStringWithOptions:0];     callback(@[[NSNull null], base64Encoded]);   } failureBlock:^(NSError *error) {     NSLog(@"that didn't work %@", error);     callback(@[error]);   }]; } 

2 Answers

Answers 1

It is basicly the same as the code you already have, it has just been split into two parts. First get a PHAsset using an id, then get the image from that asset using the PHImageManager.

  • To get the PHAsset from the library use

[+ (PHFetchResult<PHAsset *> *)fetchAssetsWithALAssetURLs:(NSArray<NSURL *> *)assetURLs options:(nullable PHFetchOptions *)options;

This method is synchronous and immediately returns an array of PHAsset but these assets don't contain any image data.

  • next use

[PHImageManager defaultManager] to get the image. This is asynchronous like the ALAssetsLibrary method. use - (PHImageRequestID)requestImageDataForAsset:(PHAsset *)asset options:(PHImageRequestOptions *)options resultHandler:(void (^)(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info))resultHandler;

The code should be something like this (obviously you have to fill in your error codes and error domain for your application)):

PHFetchResult* results = [PHAsset fetchAssetsWithLocalIdentifiers:@[input] options:nil]; PHAsset *asset = [results firstObject]; if (asset) {     [[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {         if (imageData){             NSString *base64Encoded = [imageData base64EncodedStringWithOptions:0];             callback(@[[NSNull null], base64Encoded]);         }else{             NSError* error = info[PHImageErrorKey];             if (!error) {                 error = [NSError errorWithDomain:@"" code:-1 userInfo:@{NSLocalizedDescriptionKey:@"image not found"}];             }             callback(nil, error);          }     }]; }else{     NSError* error = [NSError errorWithDomain:@"" code:-1 userInfo:@{NSLocalizedDescriptionKey:@"asset not found"}];     callback(nil, error); } 

Answers 2

You can see the api in PHAsset+ (PHFetchResult<PHAsset *> *)fetchAssetsWithALAssetURLs:(NSArray<NSURL *> *)assetURLs options:(nullable PHFetchOptions *)options;

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment