UIImagePickerController 无法获取本地图像 url
UIImagePickerController unable to fetch local image url
我正在尝试通过 UIImagePickerController 选取图像并将其上传到服务器来上传图像。为此,我需要图像的实际本地路径 (url)。由于我的目标是 iOS 9.0 及更高版本,因此我使用的是照片框架。
我能够从 PHAsset
获取文件名以及 url 。我也在检查文件是否存在于此 url,但是当我尝试上传图像时,我不确定这是否是提供给 [=19] 的正确 url =] 服务器上的脚本。 php 脚本需要文件名、设备上的实际位置以及文件数据。
这是我的代码:
#import "ViewController.h"
#import <Photos/Photos.h>
#import <MobileCoreServices/MobileCoreServices.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
switch (status) {
case PHAuthorizationStatusAuthorized:
NSLog(@"PHAuthorizationStatusAuthorized");
break;
case PHAuthorizationStatusDenied:
NSLog(@"PHAuthorizationStatusDenied");
break;
case PHAuthorizationStatusNotDetermined:
NSLog(@"PHAuthorizationStatusNotDetermined");
break;
case PHAuthorizationStatusRestricted:
NSLog(@"PHAuthorizationStatusRestricted");
break;
}
}];
NSLog(@"%@",NSHomeDirectory());
}
- (IBAction)fileSelect:(id)sender {
UIAlertController * actionSheet = [UIAlertController alertControllerWithTitle:nil message:@"File oprions:" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction * camera = [UIAlertAction actionWithTitle:@"Take photo with camera" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"Camera");
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
// Delegate is self
imagePicker.delegate = self;
// Allow editing of image ?
// Show image picker
//[[UINavigationBar appearance] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[self presentViewController:imagePicker animated:YES completion:nil];
}];
UIAlertAction * gallery = [UIAlertAction actionWithTitle:@"Choose an existing photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"Gallery");
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
// Delegate is self
imagePicker.delegate = self;
// Allow editing of image ?
// Show image picker
//[[UINavigationBar appearance] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[self presentViewController:imagePicker animated:YES completion:nil];
}];
UIAlertAction * document = [UIAlertAction actionWithTitle:@"Choose a document" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"Document");
NSArray *types = @[(NSString*)kUTTypeImage,
(NSString*)kUTTypeSpreadsheet,
(NSString*)kUTTypePresentation,
(NSString*)kUTTypeDatabase,
(NSString*)kUTTypeFolder,
(NSString*)kUTTypeZipArchive,
(NSString*)kUTTypeVideo,
(NSString*)kUTTypePDF,
(NSString*)kUTTypeMovie,
(NSString*)kUTTypeAudio,
(NSString*)kUTTypeMPEG,
(NSString*)kUTTypeMPEG2Video,
(NSString*)kUTTypeMP3,
(NSString*)kUTTypeMPEG4,
(NSString*)kUTTypeMPEG4Audio,
(NSString*)kUTTypeJPEG,
(NSString*)kUTTypePNG,
(NSString*)kUTTypeGIF,
(NSString*)kUTTypeRTFD,
(NSString*)kUTTypeWebArchive,
(NSString*)kUTTypeText,
(NSString*)kUTTypePlainText,
(NSString*)kUTTypeRTF];
//Create a object of document picker view and set the mode to Import
UIDocumentPickerViewController *docPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:types inMode:UIDocumentPickerModeImport];
//Set the delegate
docPicker.delegate = self;
//present the document picker
[self presentViewController:docPicker animated:YES completion:nil];
}];
UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"Cancelled");
}];
[actionSheet addAction:camera];
[actionSheet addAction:gallery];
[actionSheet addAction:document];
[actionSheet addAction:cancel];
//For iPad a PopOverViewController is needed
UIPopoverPresentationController * popoverController = actionSheet.popoverPresentationController;
actionSheet.modalPresentationStyle = UIModalPresentationPopover;
popoverController.sourceView = self.view;
popoverController.sourceRect = CGRectMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2, 0, 0);
popoverController.permittedArrowDirections = 0;
popoverController.delegate = self;
[self presentViewController:actionSheet animated:true completion:nil];
}
#pragma mark - Image Picker Delegate
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
NSLog(@"Image picked");
NSLog(@"%@",info);
if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary)
{
// NSData * data = UIImageJPEGRepresentation([info valueForKey:@"UIImagePickerControllerOriginalImage"], 0.5);
//
// NSString * path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/image.JPEG"];
// [data writeToFile:path atomically:true];
}
else
{
UIImageWriteToSavedPhotosAlbum([info valueForKey:@"UIImagePickerControllerOriginalImage"], nil, nil, nil);
}
UIImageView * imgView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
imgView.contentMode = UIViewContentModeScaleAspectFit;
imgView.image = [info valueForKey:@"UIImagePickerControllerOriginalImage"];
/* //Works in simulator, iOS 10+, iPhone
NSURL * fileurl = [info valueForKey:@"UIImagePickerControllerImageURL"];
NSMutableString * filepath = [NSMutableString stringWithFormat:@"%@",fileurl];
[filepath replaceOccurrencesOfString:@"file://" withString:@"" options:0 range:NSMakeRange(0, filepath.length)];
*/
NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[refURL] options:nil];
PHAsset *asset = [result firstObject];
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
UIImage* newImage = [UIImage imageWithData:imageData];
imgView.image = newImage;
}];
NSMutableString * __block filepath = nil;
NSString __block *filename = [[result firstObject] filename];
[result enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
PHAsset *asset = (PHAsset *)obj;
[asset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
NSLog(@"URL:%@", contentEditingInput.fullSizeImageURL.absoluteString);
//file:///var/mobile/Media/PhotoData/CPLAssets/group125/0888AEED-48C6-4E6E-93AB-CE99A6E706AF.JPG
NSString* path = [contentEditingInput.fullSizeImageURL.absoluteString substringFromIndex:7];//screw all the crap of file://
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isExist = [fileManager fileExistsAtPath:path];
if (isExist)
filepath = [path mutableCopy];
else {
NSLog(@"damn");
}
}];
}];
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:@"UIImagePicker"
message:@"Image picked"
preferredStyle:UIAlertControllerStyleAlert];
[alertController.view addSubview:imgView];
[alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self uploadImage:imgView.image withPath:filepath andName:filename];// works perfectly if provided with proper filepath
}]];
[self dismissViewControllerAnimated:true completion:nil];
[self presentViewController:alertController animated:YES completion:nil];
}
@end
I only wish to know where am I going wrong. Is
file:///var/mobile/Media/PhotoData/CPLAssets/group125/0888AEED-48C6-4E6E-93AB-CE99A6E706AF.JPG
the proper filepath?
您不必将本地图像 URL 传递到服务器。请查看以下示例 Swift 代码。希望您能够将其转换为 objective-c
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let chosenImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
let imageData = UIImageJPEGRepresentation(chosenImage,0.5)
var imageFileName = "default_name.jpg"
if let imageUrl = info["UIImagePickerControllerImageURL"] as? URL {
imageFileName = imageUrl.absoluteURL.lastPathComponent
}
//
// Now pass imageData and imageFileName to the server
//
} else {
print("Error while fetching image")
}
dismiss(animated:true, completion: nil)
}
PHP脚本只需要数据格式和文件名中的图像以及您要提供的文件。只需命名一个文件,您可以保留对您的系统有意义的任何内容。
无需提供文件路径,因为您已经以二进制形式提供了图像。所以你应该重新实现你的 uploadImage: 方法来只接收数据和文件名。
我正在尝试通过 UIImagePickerController 选取图像并将其上传到服务器来上传图像。为此,我需要图像的实际本地路径 (url)。由于我的目标是 iOS 9.0 及更高版本,因此我使用的是照片框架。
我能够从 PHAsset
获取文件名以及 url 。我也在检查文件是否存在于此 url,但是当我尝试上传图像时,我不确定这是否是提供给 [=19] 的正确 url =] 服务器上的脚本。 php 脚本需要文件名、设备上的实际位置以及文件数据。
这是我的代码:
#import "ViewController.h"
#import <Photos/Photos.h>
#import <MobileCoreServices/MobileCoreServices.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
switch (status) {
case PHAuthorizationStatusAuthorized:
NSLog(@"PHAuthorizationStatusAuthorized");
break;
case PHAuthorizationStatusDenied:
NSLog(@"PHAuthorizationStatusDenied");
break;
case PHAuthorizationStatusNotDetermined:
NSLog(@"PHAuthorizationStatusNotDetermined");
break;
case PHAuthorizationStatusRestricted:
NSLog(@"PHAuthorizationStatusRestricted");
break;
}
}];
NSLog(@"%@",NSHomeDirectory());
}
- (IBAction)fileSelect:(id)sender {
UIAlertController * actionSheet = [UIAlertController alertControllerWithTitle:nil message:@"File oprions:" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction * camera = [UIAlertAction actionWithTitle:@"Take photo with camera" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"Camera");
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
// Delegate is self
imagePicker.delegate = self;
// Allow editing of image ?
// Show image picker
//[[UINavigationBar appearance] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[self presentViewController:imagePicker animated:YES completion:nil];
}];
UIAlertAction * gallery = [UIAlertAction actionWithTitle:@"Choose an existing photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"Gallery");
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
// Delegate is self
imagePicker.delegate = self;
// Allow editing of image ?
// Show image picker
//[[UINavigationBar appearance] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[self presentViewController:imagePicker animated:YES completion:nil];
}];
UIAlertAction * document = [UIAlertAction actionWithTitle:@"Choose a document" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"Document");
NSArray *types = @[(NSString*)kUTTypeImage,
(NSString*)kUTTypeSpreadsheet,
(NSString*)kUTTypePresentation,
(NSString*)kUTTypeDatabase,
(NSString*)kUTTypeFolder,
(NSString*)kUTTypeZipArchive,
(NSString*)kUTTypeVideo,
(NSString*)kUTTypePDF,
(NSString*)kUTTypeMovie,
(NSString*)kUTTypeAudio,
(NSString*)kUTTypeMPEG,
(NSString*)kUTTypeMPEG2Video,
(NSString*)kUTTypeMP3,
(NSString*)kUTTypeMPEG4,
(NSString*)kUTTypeMPEG4Audio,
(NSString*)kUTTypeJPEG,
(NSString*)kUTTypePNG,
(NSString*)kUTTypeGIF,
(NSString*)kUTTypeRTFD,
(NSString*)kUTTypeWebArchive,
(NSString*)kUTTypeText,
(NSString*)kUTTypePlainText,
(NSString*)kUTTypeRTF];
//Create a object of document picker view and set the mode to Import
UIDocumentPickerViewController *docPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:types inMode:UIDocumentPickerModeImport];
//Set the delegate
docPicker.delegate = self;
//present the document picker
[self presentViewController:docPicker animated:YES completion:nil];
}];
UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"Cancelled");
}];
[actionSheet addAction:camera];
[actionSheet addAction:gallery];
[actionSheet addAction:document];
[actionSheet addAction:cancel];
//For iPad a PopOverViewController is needed
UIPopoverPresentationController * popoverController = actionSheet.popoverPresentationController;
actionSheet.modalPresentationStyle = UIModalPresentationPopover;
popoverController.sourceView = self.view;
popoverController.sourceRect = CGRectMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2, 0, 0);
popoverController.permittedArrowDirections = 0;
popoverController.delegate = self;
[self presentViewController:actionSheet animated:true completion:nil];
}
#pragma mark - Image Picker Delegate
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
NSLog(@"Image picked");
NSLog(@"%@",info);
if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary)
{
// NSData * data = UIImageJPEGRepresentation([info valueForKey:@"UIImagePickerControllerOriginalImage"], 0.5);
//
// NSString * path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/image.JPEG"];
// [data writeToFile:path atomically:true];
}
else
{
UIImageWriteToSavedPhotosAlbum([info valueForKey:@"UIImagePickerControllerOriginalImage"], nil, nil, nil);
}
UIImageView * imgView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
imgView.contentMode = UIViewContentModeScaleAspectFit;
imgView.image = [info valueForKey:@"UIImagePickerControllerOriginalImage"];
/* //Works in simulator, iOS 10+, iPhone
NSURL * fileurl = [info valueForKey:@"UIImagePickerControllerImageURL"];
NSMutableString * filepath = [NSMutableString stringWithFormat:@"%@",fileurl];
[filepath replaceOccurrencesOfString:@"file://" withString:@"" options:0 range:NSMakeRange(0, filepath.length)];
*/
NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[refURL] options:nil];
PHAsset *asset = [result firstObject];
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
UIImage* newImage = [UIImage imageWithData:imageData];
imgView.image = newImage;
}];
NSMutableString * __block filepath = nil;
NSString __block *filename = [[result firstObject] filename];
[result enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
PHAsset *asset = (PHAsset *)obj;
[asset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
NSLog(@"URL:%@", contentEditingInput.fullSizeImageURL.absoluteString);
//file:///var/mobile/Media/PhotoData/CPLAssets/group125/0888AEED-48C6-4E6E-93AB-CE99A6E706AF.JPG
NSString* path = [contentEditingInput.fullSizeImageURL.absoluteString substringFromIndex:7];//screw all the crap of file://
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isExist = [fileManager fileExistsAtPath:path];
if (isExist)
filepath = [path mutableCopy];
else {
NSLog(@"damn");
}
}];
}];
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:@"UIImagePicker"
message:@"Image picked"
preferredStyle:UIAlertControllerStyleAlert];
[alertController.view addSubview:imgView];
[alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self uploadImage:imgView.image withPath:filepath andName:filename];// works perfectly if provided with proper filepath
}]];
[self dismissViewControllerAnimated:true completion:nil];
[self presentViewController:alertController animated:YES completion:nil];
}
@end
I only wish to know where am I going wrong. Is file:///var/mobile/Media/PhotoData/CPLAssets/group125/0888AEED-48C6-4E6E-93AB-CE99A6E706AF.JPG the proper filepath?
您不必将本地图像 URL 传递到服务器。请查看以下示例 Swift 代码。希望您能够将其转换为 objective-c
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let chosenImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
let imageData = UIImageJPEGRepresentation(chosenImage,0.5)
var imageFileName = "default_name.jpg"
if let imageUrl = info["UIImagePickerControllerImageURL"] as? URL {
imageFileName = imageUrl.absoluteURL.lastPathComponent
}
//
// Now pass imageData and imageFileName to the server
//
} else {
print("Error while fetching image")
}
dismiss(animated:true, completion: nil)
}
PHP脚本只需要数据格式和文件名中的图像以及您要提供的文件。只需命名一个文件,您可以保留对您的系统有意义的任何内容。
无需提供文件路径,因为您已经以二进制形式提供了图像。所以你应该重新实现你的 uploadImage: 方法来只接收数据和文件名。