Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload image that was taken from UIImagePickerController

After user choose image from the iPhone library with UIImagePickerController, I want to upload it to my server using ASIHTTPRequest library.

I know that with ASIHTTPRequest I can upload a file with the file's URl, but how do I get the image URL?

I know I can get the image UIImagePickerControllerReferenceURL, that look like this:

"assets-library://asset/asset.JPG?id=F2829B2E-6C6B-4569-932E-7DB03FBF7763&ext=JPG"

is this the URL I need to use?

like image 681
user1590031 Avatar asked Aug 27 '12 08:08

user1590031


4 Answers

There are lots of answers that suggest UIImageJPEGRepresentation or UIImagePNGRepresentation. But these solutions will convert the original file while this question is actually about saving the file AS IS.

It looks like uploading the file directly from assets library is impossible. But it can be accessed using PHImageManager to get the actual image data. Here's how:

Swift 3 (Xcode 8, only for iOS 8.0 and higher)

1) Import the Photos framework

import Photos

2) In the imagePickerController(_:didFinishPickingMediaWithInfo:) get the asset URL

3) Fetch assets using fetchAssets(withALAssetURLs:options:)

4) Get the actual image data with requestImageData(for:options:resultHandler:). In the result handler of this method you will have the data as well as URL to the file (the URL can be accessed on Simulator, but unfortunately is not accessible on the device - in my tests startAccessingSecurityScopedResource() always returned false). However this URL is still useful to find out the file name.

Example code:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    dismiss(animated: true, completion: nil)
    if let assetURL = info[UIImagePickerControllerReferenceURL] as? URL,
        let asset = PHAsset.fetchAssets(withALAssetURLs: [assetURL], options: nil).firstObject,
        let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first,
        let targetURL = Foundation.URL(string: "file://\(documentsPath)") {

        PHImageManager.default().requestImageData(for: asset, options: nil, resultHandler: { (data, UTI, _, info) in
            if let imageURL = info?["PHImageFileURLKey"] as? URL,
                   imageData = data {
                    do {
                        try data.write(to: targetURL.appendingPathComponent(imageURL.lastPathComponent), options: .atomic)

                        self.proceedWithUploadFromPath(targetPath: targetURL.appendingPathComponent(imageURL.lastPathComponent))

                   } catch { print(error) }
                }
            }
        })
    }
}

This will give you the file AS IS including its correct name and you can even get its UTI to determine correct mimetype (in addition to determining it via file extension) while preparing multipart body for upload.

like image 67
Vitalii Avatar answered Nov 03 '22 02:11

Vitalii


There are two ways

1:

You can upload the image using the imagePickerController delegate

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{   

    UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
    //Upload your image
}

2:

You can save the picked image url and upload later using this

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{

    NSString *imageUrl = [NSString stringWithFormat:@"%@",[info valueForKey:UIImagePickerControllerReferenceURL]];
    //Save the imageUrl
}

-(void)UploadTheImage:(NSString *)imageUrl{

 NSURL *url = [[NSURL alloc] initWithString:imageUrl];
 typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
 typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);    

 ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset){

  ALAssetRepresentation *rep = [myasset defaultRepresentation];
  CGImageRef iref = [rep fullResolutionImage];
  UIImage *myImage = nil;   

  if (ref) {
      myImage = [UIImage imageWithCGImage:iref scale:[rep scale] orientation:(UIImageOrientation)[rep orientation]];

        //upload the image   
     }      
  };      

  ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror){

  };          


  ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
 [assetslibrary assetForURL:url resultBlock:result block failureBlock:failureblock];    

}

Notes: Please make sure the scope of ALAssetsLibrary object while using ARC.Better to use the ALAssetsLibrary object as a singleton.

like image 36
Shamsudheen TK Avatar answered Nov 03 '22 02:11

Shamsudheen TK


Save the photo in Document directory and use that url to upload.For example

NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Test.jpg"];
[UIImageJPEGRepresentation(img, 1.0) writeToFile:jpgPath atomically:YES];

upload this image as [request setFile:jpgPath forKey:@"image"];

like image 3
Ab'initio Avatar answered Nov 03 '22 03:11

Ab'initio


To get the image UIImagePickerControllerReferenceUR. This Sample Code is given below

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        ALAssetRepresentation *representation = [myasset defaultRepresentation];
        NSString *fileName = [representation filename];
        NSLog(@"fileName : %@",fileName);

        CGImageRef ref = [representation fullResolutionImage];
        ALAssetOrientation orientation = [[myasset valueForProperty:@"ALAssetPropertyOrientation"] intValue];
        UIImage *image = [UIImage imageWithCGImage:ref scale:1.0 orientation:(UIImageOrientation)orientation];

    };

    ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
    [assetslibrary assetForURL:imageURL 
                   resultBlock:resultblock
                  failureBlock:nil];

}

NOTE: It works only in iOS 5 and later.

like image 1
Paresh Navadiya Avatar answered Nov 03 '22 01:11

Paresh Navadiya