Guardar y cargar UIImages

Entonces, en mi aplicación, quiero que el usuario pueda seleccionar / tomar una foto, luego mostrar esa image en un UIImageView . El problema es que, a través de mi investigación, he encontrado muchas forms de save / cargar imágenes, pero aparentemente hay un problema para saber si la image es un .png o .jpg . Así que he intentado un montón de cosas diferentes, y parece que no pueden hacerlo funcionar. Gracias de antemano por cualquier ayuda.

Aquí está mi código por una vez que se selecciona la image (le doy al usuario la opción de tomar una foto o seleccionar una image del rollo de la camera):

 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage]; if (!image) image = [info objectForKey:UIImagePickerControllerOriginalImage]; if (!image) return; NSData *imageData = UIImageJPEGRepresentation(image, 1.0); NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *whichPic = @"" if (whichPicture == pictureA) whichPic = @"kpictureA"; else whichPic = @"kpictureB"; [defaults setObject:imageData forKey:whichPic]; [defaults synchronize]; 

Intenté esto, pero no pude lograr que funcionara:

 // Create paths to output images NSString *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Before.png"]; NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Before.jpg"]; // Write a UIImage to JPEG with minimum compression (best quality) // The value 'image' must be a UIImage object // The value '1.0' represents image compression quality as value from 0.0 to 1.0 [UIImageJPEGRepresentation(image, 1.0) writeToFile:jpgPath atomically:YES]; // Write image to PNG [UIImagePNGRepresentation(image) writeToFile:pngPath atomically:YES]; // Let's check to see if files were successfully written... // Create file manager NSError *error; NSFileManager *fileMgr = [NSFileManager defaultManager]; // Point to Document directory NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; // Write out the contents of home directory to console NSLog(@"Documents directory: %@", [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error]); */ 

También probé esto, pero fue en vano:

  ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata]; [library writeImageToSavedPhotosAlbum:[image CGImage] metadata:metadata completionBlock:nil]; 

Luego, para cargar la image cuando se carga la vista, probé esto:

  // Create paths to output images NSString *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Before.png"]; NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Before.jpg"]; // Let's check to see if files were successfully written... // Create file manager NSError *error; NSFileManager *fileMgr = [NSFileManager defaultManager]; // Point to Document directory NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; // Write out the contents of home directory to console NSLog(@"Documents directory: %@", [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error]); if ([[fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error] containsObject:@"pictureA.png"]) { NSData *imageData = [fileMgr contentsAtPath:@"Documents/Before.png"]; [pcitureAButton setImage:[UIImage imageWithData:imageData] forState:UIControlStateNormal]; } else if ([fileMgr contentsAtPath:@"Documents/pictureA.png"]) { NSData *imageData = [fileMgr contentsAtPath:@"Documents/pictureA.png"]; [pictureButton setImage:[UIImage imageWithData:imageData] forState:UIControlStateNormal]; } 

Entonces probé esto:

  if([defaults valueForKey:@"kPictureA"]) { UIImage *image = [[UIImage alloc] initWithData:[defaults valueForKey:kPictureA]]; [pictureAButton setImage:image forState:UIControlStateNormal]; } 

y finalmente intenté usar NSData con NSUserDefeaults .

Preferiría usar NSUserDefaults porque me siento más cómodo con ellos, pero ciertamente abro a una solución que funcione.

Esto es lo que uso:

Tomar una foto

 - (IBAction)openCamera:(id)sender{ if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == YES){ UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init]; cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera; cameraUI.allowsEditing = YES; cameraUI.delegate = self; //Displays only picture option; cameraUI.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage]; [self presentModalViewController: cameraUI animated: YES]; [cameraUI release]; }else{ [self openPhotoLibrary:nil]; } } 

Elegir foto de la biblioteca

 - (IBAction)openPhotoLibrary:(id)sender{ UIImagePickerController *libraryPicker = [[UIImagePickerController alloc] init]; libraryPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; libraryPicker.allowsEditing = YES; libraryPicker.delegate = self; //Displays only picture option; libraryPicker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage]; [self presentModalViewController: libraryPicker animated: YES]; [libraryPicker release]; } 

En respuesta al usuario, toque Cancelar.

 - (void)imagePickerControllerDidCancel: (UIImagePickerController *) picker { [[picker parentViewController] dismissModalViewControllerAnimated: YES]; [picker release]; } 

Responder al usuario que acepta una image recién capturada.

 - (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) description { NSString *mediaType = [description objectForKey: UIImagePickerControllerMediaType]; UIImage *originalImage, *editedImage, *imageToSave; // Handle a still image capture if (CFStringCompare ((CFStringRef) mediaType, kUTTypeImage, 0) == kCFCompareEqualTo) { editedImage = (UIImage *) [description objectForKey:UIImagePickerControllerEditedImage]; originalImage = (UIImage *) [description objectForKey:UIImagePickerControllerOriginalImage]; if (editedImage) { imageToSave = editedImage; } else { imageToSave = originalImage; } // Save the new image (original or edited) to the Camera Roll if(picker.sourceType == UIImagePickerControllerSourceTypeCamera) UIImageWriteToSavedPhotosAlbum (imageToSave, nil, nil , nil); //Save your UIImage here myImage = imageToSave; } [self dismissModalViewControllerAnimated:YES]; } 

EDITAR

Para verificar el tipo de file, puede examinar el primer byte NSData utilizando el siguiente método:

 + (NSString *)contentTypeForImageData:(NSData *)data { uint8_t c; [data getBytes:&c length:1]; switch (c) { case 0xFF: return @"image/jpeg"; case 0x89: return @"image/png"; case 0x47: return @"image/gif"; case 0x49: case 0x4D: return @"image/tiff"; } return nil; } 

Una vez que tenga la Imagen en un UIImageView, puede decidir savelo en el formatting que prefiera

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *imageName = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Image.png"]; NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)]; [imageData writeToFile:imageName atomically:YES]; 

La línea NSData convierte la image de UIImageView.image en un formatting PNG y, por lo tanto, se guarda como un png con la extensión de file .png

SI quería savela como JPEG, simplemente cambie el ImageName a @ "Image.jpg" y cambie UIImagePNGRepresentation a UIImageJPEGRrepresentation

ahora la misma image se guarda como un jpeg. Usted decide el formatting y luego usa la extensión de file coincidente y la llamada de Representación

La respuesta de Cyprian le proporciona un método para leer la image (del file en NSData) y verificar que es un PNG o JPEG, etc.