Save images in NSUserDefaults?

2019-01-01 15:13发布

Is it possible to save images into NSUserDefaults as an object and then retrieve for further use?

12条回答
浪荡孟婆
2楼-- · 2019-01-01 15:29

While it is possible to save a UIImage to NSUserDefaults, it is often not recommended as it is not the most efficient way to save images; a more efficient way is to save your image in the application's Documents Directory.

For the purpose of this question, I have attached the answer to your question, along with the more efficient way of saving a UIImage.


NSUserDefaults (Not Recommended)

Saving to NSUserDefaults

This method allows you to save any UIImage to NSUserDefaults.

-(void)saveImageToUserDefaults:(UIImage *)image ofType:(NSString *)extension forKey:(NSString *)key {
    NSData * data;

    if ([[extension lowercaseString] isEqualToString:@"png"]) {
        data = UIImagePNGRepresentation(image);
    } else if ([[extension lowercaseString] isEqualToString:@"jpg"]) {
        data = UIImageJPEGRepresentation(image, 1.0);
    }

    NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:data forKey:key];
    [userDefaults synchronize];
}

This is how you call it:

[self saveImageToUserDefaults:image ofType:@"jpg" forKey:@"myImage"];
[[NSUserDefaults standardUserDefaults] synchronize];

Loading From NSUserDefaults

This method allows you to load any UIImage from NSUserDefaults.

-(UIImage *)loadImageFromUserDefaultsForKey:(NSString *)key {
    NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
    return [UIImage imageWithData:[userDefaults objectForKey:key]];
}

This is how you call it:

UIImage * image = [self loadImageFromUserDefaultsForKey:@"myImage"];

A Better Alternative

Saving to Documents Directory

This method allows you to save any UIImage to the Documents Directory within the app.

-(void)saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
    if ([[extension lowercaseString] isEqualToString:@"png"]) {
        [UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]] options:NSAtomicWrite error:nil];
    } else if ([[extension lowercaseString] isEqualToString:@"jpg"] || [[extension lowercaseString] isEqualToString:@"jpeg"]) {
        [UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]] options:NSAtomicWrite error:nil];
    } else {
        NSLog(@"Image Save Failed\nExtension: (%@) is not recognized, use (PNG/JPG)", extension);
    }
}

This is how you call it:

NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
[self saveImage:image withFileName:@"Ball" ofType:@"jpg" inDirectory:documentsDirectory];

Loading From Documents Directory

This method allows you to load any UIImage from the application's Documents Directory.

-(UIImage *)loadImageWithFileName:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
    UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.%@", directoryPath, fileName, [extension lowercaseString]]];

    return result;
}

This is how you call it:

NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
UIImage * image = [self loadImageWithFileName:@"Ball" ofType:@"jpg" inDirectory:documentsDirectory];

A Different Alternative

Saving UIImage to Photo Library

This method allows you to save any UIImage to the device's Photo Library, and is called as follows:

UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

Saving multiple UIImages to Photo Library

This method allows you to save multiple UIImages to the device's Photo Library.

-(void)saveImagesToPhotoAlbums:(NSArray *)images {
    for (int x = 0; x < [images count]; x++) {
        UIImage * image = [images objectAtIndex:x];

        if (image != nil) UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
    }
}

This is how you call it:

[self saveImagesToPhotoAlbums:images];

Where images is your NSArray composed of UIImages.

查看更多
梦该遗忘
3楼-- · 2019-01-01 15:30

Yes, you can use. But since it is for storage of preferences, you can better save images to document folder.

And you can have the path in the NSUserDefaults, if required.

查看更多
其实,你不懂
4楼-- · 2019-01-01 15:31

Yes , technically possible as in

[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image) forKey:@"foo"];

But not advisable because plists are not appropriate places for large blobs of binary data especially User Prefs. It would be better to save image to user docs folder and store the reference to that object as a URL or path.

查看更多
孤独寂梦人
5楼-- · 2019-01-01 15:31

For Swift 3 and JPG format

Register Default Image :

UserDefaults.standard.register(defaults: ["key":UIImageJPEGRepresentation(image, 100)!])

Save Image :

UserDefaults.standard.set(UIImageJPEGRepresentation(image, 100), forKey: "key")

Load Image :

let imageData = UserDefaults.standard.value(forKey: "key") as! Data
let imageFromData = UIImage(data: imageData)!
查看更多
琉璃瓶的回忆
6楼-- · 2019-01-01 15:38

It's technically possible, but it's not advisable. Save the image to disk instead. NSUserDefaults is meant for small settings, not big binary data files.

查看更多
唯独是你
7楼-- · 2019-01-01 15:39

To save an image in NSUserDefaults:

[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image) forKey:key];

To retrieve an image from NSUserDefaults:

NSData* imageData = [[NSUserDefaults standardUserDefaults] objectForKey:key];
UIImage* image = [UIImage imageWithData:imageData];
查看更多
登录 后发表回答