So In my app, I want the user to be able to select/take a picture, then show that image in a UIImageView
. The problem is, through my research, I've found many ways to save/load images, but apparently there is a problem with knowing whether the image is a .png
or .jpg
. So I've tried a bunch of different thing, and can't seem to get it to work. Thanks in advance for any help.
Heres my code for once the image is selected (I give the user the option to take a picture or select a picture from the camera roll):
- (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];
I Tried this, but couldn't get it to work:
// 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]);
*/
I also tried this, but to no avail:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
[library writeImageToSavedPhotosAlbum:[image CGImage] metadata:metadata completionBlock:nil];
Then to load the image when the view loads, I tried this:
// 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];
}
Then I tried this:
if([defaults valueForKey:@"kPictureA"]) {
UIImage *image = [[UIImage alloc] initWithData:[defaults valueForKey:kPictureA]];
[pictureAButton setImage:image forState:UIControlStateNormal];
}
and finally I tried a using NSData
with NSUserDefeaults
.
I would prefer to use NSUserDefaults because I'm most comfortable with them, but I certainly open to solution that works.
This is what I use:
Take a photo
- (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];
}
}
Choose photo from library
- (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];
}
Responding to the user tapping Cancel.
- (void)imagePickerControllerDidCancel: (UIImagePickerController *) picker {
[[picker parentViewController] dismissModalViewControllerAnimated: YES];
[picker release];
}
Responding to the user accepting a newly-captured picture
- (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];
}
EDIT
To check the file type you can examin the first NSData byte using the following method:
+ (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;
}
Once you have the Image in a UIImageView you can decide to save it in which format you prefer
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];
The NSData line converts the image from the UIImageView.image into a PNG format and thus is saved as a png with the .png file extension
IF I wanted to save it as a JPEG simply change the imageName to @"Image.jpg" and change UIImagePNGRepresentation to UIImageJPEGRepresentation
now the same image is saved as a jpeg. You decide the format and then use the matching file extension and Representation call
Cyprian answer gives you a method to read the image (from file into NSData) and verify that it is a PNG or JPEG, etc..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With