Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving and Loading UIImages

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.

like image 473
Andrew Avatar asked Feb 21 '23 23:02

Andrew


2 Answers

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;
}
like image 80
Cyprian Avatar answered Feb 26 '23 09:02

Cyprian


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..

like image 45
BarryF Avatar answered Feb 26 '23 07:02

BarryF