可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am working to capture an image that is returned in 4.0 using
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
// MediaType can be kUTTypeImage or kUTTypeMovie. If it's a movie then you
// can get the URL to the actual file itself. This example only looks for images.
//
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
// NSString* videoUrl = [info objectForKey:UIImagePickerControllerMediaURL];
// Try getting the edited image first. If it doesn't exist then you get the
// original image.
//
if (CFStringCompare((CFStringRef) mediaType, kUTTypeImage, 0) == kCFCompareEqualTo) {
UIImage* picture = [info objectForKey:UIImagePickerControllerEditedImage];
if (!picture)
picture = [info objectForKey:UIImagePickerControllerOriginalImage];
// **picture is always nil
// info dictionary count = 1
}
}
What is happening is that the info dictionary always returns with a single entry:
{
UIImagePickerControllerMediaType =
"public.image";
which is great, but there is never an image.
I was using a great example from this forum to do this, and I am pretty sure the calls are correct, but never an image.
Thanks in advance!
回答1:
I know this is many months later, but I struggled with this for hours, and found this same question all over this site and iphonedevsdk.com, but never with a working answer.
To summarize, if the image was picked from the camera roll/photo library it worked fine, but if the image was a new photo take with the camera it never worked. Well, here's how to make it work for both:
You have to dismiss and release the UIImagePickerController before you try to do anything with the info dictionary. To be super-clear:
This DOES NOT work:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
// No good with the edited image (if you allowed editing)
myUIImageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
// AND no good with the original image
myUIImageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
// AND no doing some other kind of assignment
UIImage *myImage = [info objectForKey:UIImagePickerControllerEditedImage];
[picker dismissModalViewControllerAnimated:YES];
[picker release];
}
In all of those cases the image will be nil.
However, via the magic of releasing the UIImagePickerController first...
This DOES work:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
[picker release];
// Edited image works great (if you allowed editing)
myUIImageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
// AND the original image works great
myUIImageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
// AND do whatever you want with it, (NSDictionary *)info is fine now
UIImage *myImage = [info objectForKey:UIImagePickerControllerEditedImage];
}
Crazy simple, but that's all there is to it.
回答2:
whilst Matthew Frederick's answer is most popular and has long been the appropriate response, as of iOS 5.0, apple made available dismissViewControllerAnimated:completion:
, to replace the now deprecated (as of iOS 6.0) dismissViewControllerAnimated:
.
performing the image info dictionary retrieval in the completion block should hopefully make more sense to all.
to take his example from above, it would now look like:
- (void) imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:^{
// Edited image works great (if you allowed editing)
myUIImageView.image = [info objectForKey:UIImagePickerControllerEditedImage];
// AND the original image works great
myUIImageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];
// AND do whatever you want with it, (NSDictionary *)info is fine now
UIImage *myImage = [info objectForKey:UIImagePickerControllerEditedImage];
}];
}
回答3:
I've tried all above, but no luck on iPad 6.0/6.1 simulator, however i've found that info contains "UIImagePickerControllerReferenceURL" key and here is my code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissViewControllerAnimated:YES completion:NULL];
UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
if(NULL == image){
[MyImageLoader loadImageFromAssertByUrl:[info objectForKey:@"UIImagePickerControllerReferenceURL"]
completion:^(UIImage* img){
//img not null here
}];
}else{
//image not null here
}
}
and code for loadImageFromAssertByUrl is:
+(void) loadImageFromAssertByUrl:(NSURL *)url completion:(void (^)(UIImage*)) completion{
ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
[assetLibrary assetForURL:url 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];
UIImage* img = [UIImage imageWithData:data];
completion(img);
} failureBlock:^(NSError *err) {
NSLog(@"Error: %@",[err localizedDescription]);
}];
}
回答4:
There's also a known bug with some versions of XCode and Mountain Lion. Check your console for this message:
2013-01-17 21:36:34.946 3sure-ios[5341:1803] Named service 'com.apple.PersistentURLTranslator.Gatekeeper' not found. assetsd is down or misconfigured. Things will not work the way you expect them to.
It probably won't work if that message appears. Check your app at the actual iOS device.
Nevetheless, restarting both simulator and XCode seems to fix the issue.
回答5:
use
[[UIImagePickerController alloc] init];
instead of
[[UIImagePickerController alloc] initWithNibName:(NSString *) bundle:(NSBundle *)];
回答6:
I had the same symptoms, but in my case it turned out I had a category on something in the UIImagePickerController hierarchy that overrode "uuid" or "setUUID"? I guess CoreData needs these methods or it gets very, very confused, and the asset library is all CoreData stuff.
回答7:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:NULL];
//Image picker for nil value
UIImage* selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
NSLog(@"my Info :: %@", info);
if(NULL == selectedImage){
UIImage * selectedImage = [PhotoViewController loadImageFromAssertByUrl:[info objectForKey:@"UIImagePickerControllerReferenceURL"]
completion:^(UIImage * selectedImage){
//img not null here
NSLog(@"img2 ::: %@", selectedImage);
uploadImg.image = selectedImage;
[self.view addSubview:PermissionView];
}];
}else{
//image not null here
NSLog(@"Up IMG00 :: %@", uploadImg.image);
NSLog(@"Sel IMG00 :: %@", selectedImage);
uploadImg.image = [selectedImage retain];
NSLog(@"Up IMG22 :: %@", uploadImg.image);
NSLog(@"Sel IMG22 :: %@", selectedImage);
}
}
+(UIImage *) loadImageFromAssertByUrl:(NSURL *)url completion:(void (^)(UIImage*)) completion{
__block UIImage* img;
ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
[assetLibrary assetForURL:url 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];
img = [UIImage imageWithData:data];
completion(img);
NSLog(@"img ::: %@", img);
} failureBlock:^(NSError *err) {
NSLog(@"Error: %@",[err localizedDescription]);
}];
return img;
}
回答8:
Following Steps needs to be followed:
1) Make UIActionSheet
2) On selection necessary source type - load resrouces
3) didFinishPickingMediaWithInfo - set image from image Dictionary recieved
- (IBAction)actionButtonUpload:(id)sender {
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self
cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Camera",@"Photo Library", nil];
[actionSheet showInView:self.view];
}
#pragma mark -- UIActionSheet Delegate
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
UIAlertView *alert;
switch (buttonIndex) {
case 0:
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
NSLog(@"No camera!");
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
} else {
alert = [[UIAlertView alloc]initWithTitle:@"Alumnikonnect" message:@"Camera is not available, please select a different media" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
}
break;
case 1:
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:picker animated:YES completion:NULL];
} else {
alert = [[UIAlertView alloc]initWithTitle:@"Alumnikonnect" message:@"Photolibrary is not available, please select a different media" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
}
break;
}
}
#pragma mark - Image picker delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
self.imageEventPic.layer.cornerRadius = self.imageEventPic.frame.size.height /2;
self.imageEventPic.layer.masksToBounds = YES;
self.imageEventPic.layer.borderWidth = 0;
self.imageEventPic.layer.borderWidth = 1.0f;
self.imageEventPic.layer.borderColor = [UIColor colorWithRed:0.212 green:0.255 blue:0.302 alpha:1.000].CGColor;
self.labelUploadPic.hidden = YES;
self.imageEventPic.image = info[UIImagePickerControllerOriginalImage];
[self dismissViewControllerAnimated:YES completion:NULL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:NULL];
}
-(UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}