iphone - open - uiimagepickercontrollerdelegate swift 4
didFinishPickingMediaWithInfo return nil photo (8)
Estoy trabajando para capturar una imagen que se devuelve en 4.0 usando
- (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
}
}
Lo que está sucediendo es que el diccionario de información siempre regresa con una sola entrada:
{UIImagePickerControllerMediaType = "public.image";
lo cual es genial, pero nunca hay una imagen.
Estaba usando un gran ejemplo de este foro para hacer esto, y estoy bastante seguro de que las llamadas son correctas, pero nunca una imagen.
¡Gracias por adelantado!
He intentado todo lo anterior, pero no tuve suerte en el simulador de iPad 6.0 / 6.1, sin embargo, he encontrado que la información contiene la clave "UIImagePickerControllerReferenceURL" y aquí está mi código:
- (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
}
}
y el código para loadImageFromAssertByUrl es:
+(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]);
}];
}
Los siguientes pasos deben seguirse:
1) Hacer UIActionSheet
2) En la selección del tipo de fuente necesaria - resrouces de carga
3) didFinishPickingMediaWithInfo - set image from image Diccionario recibido
- (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;
}
Sé que esto es muchos meses después, pero luché con esto durante horas, y encontré esta misma pregunta en todo este sitio y iphonedevsdk.com, pero nunca con una respuesta funcional.
En resumen, si la imagen fue tomada de la biblioteca de rollo / fotografía de la cámara, funcionó bien, pero si la imagen era una toma de fotografía nueva con la cámara, nunca funcionó. Bueno, aquí está cómo hacer que funcione para ambos:
Debe descartar y liberar UIImagePickerController antes de intentar hacer algo con el diccionario de información. Para ser súper claro:
Esto no funciona:
- (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];
}
En todos esos casos, la imagen será nula.
Sin embargo, a través de la magia de liberar UIImagePickerController primero ...
Esto SÍ funciona:
- (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];
}
Loco simple, pero eso es todo.
También hay un error conocido con algunas versiones de XCode y Mountain Lion. Revisa tu consola por este mensaje:
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.
Probablemente no funcionará si aparece ese mensaje. Verifique su aplicación en el dispositivo iOS real.
Sin embargo, reiniciar tanto el simulador como XCode parece solucionar el problema.
Tenía los mismos síntomas, pero en mi caso resultó que tenía una categoría en algo en la jerarquía UIImagePickerController que anulaba "uuid" o "setUUID". Supongo que CoreData necesita estos métodos o se vuelve muy, muy confuso, y la biblioteca de activos es todo material de CoreData.
mientras que la respuesta de Matthew Frederick es la más popular y ha sido durante mucho tiempo la respuesta adecuada, desde iOS 5.0, Apple hizo disponible dismissViewControllerAnimated:completion:
para reemplazar el ahora obsoleto (a partir de iOS 6.0) dismissViewControllerAnimated:
la realización de la recuperación del diccionario de información de imagen en el bloque de finalización debería tener más sentido para todos.
para tomar su ejemplo de arriba, ahora se vería así:
- (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];
}];
}
utilizar
[[UIImagePickerController alloc] init];
en lugar de
[[UIImagePickerController alloc] initWithNibName:(NSString *) bundle:(NSBundle *)];
-(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;
}