是否可以将图像保存NSUserDefaults
为一个对象,然后检索以供进一步使用?
Answers:
注意!如果您要在iOS8 / XCODE6以下工作,请参阅下面的更新
对于仍在寻找答案的用户,这里提供了“建议”方式的代码,用于将图像保存在NSUserDefaults中。您不应该将图像数据直接保存到NSUserDefaults中!
写入数据:
// Get image data. Here you can use UIImagePNGRepresentation if you need transparency
NSData *imageData = UIImageJPEGRepresentation(image, 1);
// Get image path in user's folder and store file with name image_CurrentTimestamp.jpg (see documentsPathForFileName below)
NSString *imagePath = [self documentsPathForFileName:[NSString stringWithFormat:@"image_%f.jpg", [NSDate timeIntervalSinceReferenceDate]]];
// Write image data to user's folder
[imageData writeToFile:imagePath atomically:YES];
// Store path in NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:imagePath forKey:kPLDefaultsAvatarUrl];
// Sync user defaults
[[NSUserDefaults standardUserDefaults] synchronize];
读取数据:
NSString *imagePath = [[NSUserDefaults standardUserDefaults] objectForKey:kPLDefaultsAvatarUrl];
if (imagePath) {
self.avatarImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imagePath]];
}
documentsPathForFileName:
- (NSString *)documentsPathForFileName:(NSString *)name {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
return [documentsPath stringByAppendingPathComponent:name];
}
对于iOS8 / XCODE6 正如以下评论中提到的tmr和DevC,xcode6 / ios8存在问题。xcode5和xcode 6安装过程之间的区别在于,xcode6会在每次在xcode中运行应用程序后更改应用程序UUID(请参阅路径中突出显示的部分:/ var / mobile / Containers / Data / Application / B0D49CF5-8FBE-4F14-87AE-FA8C16A678B1 / Documents / image.jpg)。
因此,有两种解决方法:
这是快速版本的代码,作为奖励(使用第二种方法):
写入数据:
let imageData = UIImageJPEGRepresentation(image, 1)
let relativePath = "image_\(NSDate.timeIntervalSinceReferenceDate()).jpg"
let path = self.documentsPathForFileName(relativePath)
imageData.writeToFile(path, atomically: true)
NSUserDefaults.standardUserDefaults().setObject(relativePath, forKey: "path")
NSUserDefaults.standardUserDefaults().synchronize()
读取数据:
let possibleOldImagePath = NSUserDefaults.standardUserDefaults().objectForKey("path") as String?
if let oldImagePath = possibleOldImagePath {
let oldFullPath = self.documentsPathForFileName(oldImagePath)
let oldImageData = NSData(contentsOfFile: oldFullPath)
// here is your saved image:
let oldImage = UIImage(data: oldImageData)
}
documentsPathForFileName:
func documentsPathForFileName(name: String) -> String {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true);
let path = paths[0] as String;
let fullPath = path.stringByAppendingPathComponent(name)
return fullPath
}
要将图像保存在NSUserDefaults中:
[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image) forKey:key];
要从NSUserDefaults检索图像:
NSData* imageData = [[NSUserDefaults standardUserDefaults] objectForKey:key];
UIImage* image = [UIImage imageWithData:imageData];
尽管可以保存UIImage
到NSUserDefaults
,但通常不建议这样做,因为它不是保存图像的最有效方法。一种更有效的方法是将图像保存在应用程序的中Documents Directory
。
出于此问题的目的,我已将答案附加到您的问题上,并提供了一种更有效的保存方法UIImage
。
保存到NSUserDefaults
此方法可将任何内容保存UIImage
到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];
}
这就是你的称呼:
[self saveImageToUserDefaults:image ofType:@"jpg" forKey:@"myImage"];
[[NSUserDefaults standardUserDefaults] synchronize];
从NSUserDefaults加载
这种方法允许你加载任何UIImage
从NSUserDefaults
。
-(UIImage *)loadImageFromUserDefaultsForKey:(NSString *)key {
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
return [UIImage imageWithData:[userDefaults objectForKey:key]];
}
这就是你的称呼:
UIImage * image = [self loadImageFromUserDefaultsForKey:@"myImage"];
保存到文档目录
通过此方法,您可以将任何内容保存UIImage
到Documents Directory
应用内。
-(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);
}
}
这就是你的称呼:
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
[self saveImage:image withFileName:@"Ball" ofType:@"jpg" inDirectory:documentsDirectory];
从文档目录加载
此方法允许您UIImage
从应用程序的中加载任何内容Documents Directory
。
-(UIImage *)loadImageWithFileName:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.%@", directoryPath, fileName, [extension lowercaseString]]];
return result;
}
这就是你的称呼:
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
UIImage * image = [self loadImageWithFileName:@"Ball" ofType:@"jpg" inDirectory:documentsDirectory];
将UIImage保存到照片库
此方法允许您将任何内容保存UIImage
到设备的Photo Library
,方法如下:
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
将多个UIImage保存到照片库
通过此方法,您可以将多个保存UIImages
到设备的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);
}
}
这就是你的称呼:
[self saveImagesToPhotoAlbums:images];
images
你是哪里NSArray
组成的UIImages
?
inDirectory:(NSString *)directoryPath
-您可以将其命名为“ myAppData”吗?
对于Swift 4
我几乎尝试了这个问题的所有内容,但没有人为我工作。我找到了解决方案。首先,我为UserDefaults创建了一个扩展,如下所示,然后仅调用get和set方法。
extension UserDefaults {
func imageForKey(key: String) -> UIImage? {
var image: UIImage?
if let imageData = data(forKey: key) {
image = NSKeyedUnarchiver.unarchiveObject(with: imageData) as? UIImage
}
return image
}
func setImage(image: UIImage?, forKey key: String) {
var imageData: NSData?
if let image = image {
imageData = NSKeyedArchiver.archivedData(withRootObject: image) as NSData?
}
set(imageData, forKey: key)
}
}
在settingsVC中将图像设置为背景我在下面使用了代码。
let croppedImage = cropImage(selectedImage, toRect: rect, viewWidth: self.view.bounds.size.width, viewHeight: self.view.bounds.size.width)
imageDefaults.setImage(image: croppedImage, forKey: "imageDefaults")
在mainVC中:
let bgImage = imageDefaults.imageForKey(key: "imageDefaults")!
对于Swift 3和JPG格式
注册默认图像:
UserDefaults.standard.register(defaults: ["key":UIImageJPEGRepresentation(image, 100)!])
保存图片 :
UserDefaults.standard.set(UIImageJPEGRepresentation(image, 100), forKey: "key")
载入图片:
let imageData = UserDefaults.standard.value(forKey: "key") as! Data
let imageFromData = UIImage(data: imageData)!
从Apple文档中,
NSUserDefaults类提供了用于访问常见类型(例如浮点数,双精度数,整数,布尔值和URL)的便捷方法。默认对象必须是属性列表,即NSData,NSString,NSNumber,NSNumber,NSDate,NSArray或NSDictionary的一个实例(或用于集合的实例的组合)。如果要存储任何其他类型的对象,通常应将其归档以创建NSData实例。
您可以这样保存图像:-
[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation([UIImage imageNamed:@"yourimage.gif"])forKey:@"key_for_your_image"];
像这样阅读:
NSData* imageData = [[NSUserDefaults standardUserDefaults]objectForKey:@"key_for_your_image"];
UIImage* image = [UIImage imageWithData:imageData];
将图像保存到NSUserDefault:
NSData *imageData;
// create NSData-object from image
imageData = UIImagePNGRepresentation([dic objectForKey:[NSString stringWithFormat:@"%d",i]]);
// save NSData-object to UserDefaults
[[NSUserDefaults standardUserDefaults] setObject:imageData forKey:[NSString stringWithFormat:@"%d",i]];
从NSUserDefault加载图像:
NSData *imageData;
// Load NSData-object from NSUserDefault
imageData = [[NSUserDefaults standardUserDefaults] valueForKey:[NSString stringWithFormat:@"%d",i]];
// get Image from NSData
[image setObject:[UIImage imageWithData:imageData] forKey:[NSString stringWithFormat:@"%d",i]];
由于此问题的Google搜索索引较高-在今天的时代,这是@NikitaTook的答案,即Swift 3和Swift 4(带有异常处理)。
注意:此类仅用于读取JPG格式的图像并将其写入文件系统。这些Userdefaults
东西应该在外面处理。
writeFile
接收jpg图像的文件名(扩展名为.jpg)及其UIImage
本身,如果可以保存则返回true,否则,如果不能写图像则返回false,此时可以将图像存储在Userdefaults
其中将是您的备份计划,或者只是重试一次。该readFile
函数接受图像文件名并返回UIImage
,如果找到传递给该函数的图像名,则返回该图像,否则仅从应用程序的资产文件夹返回默认的占位符图像(这样可以避免令人讨厌的崩溃或其他问题)怪异的行为)。
import Foundation
import UIKit
class ReadWriteFileFS{
func writeFile(_ image: UIImage, _ imgName: String) -> Bool{
let imageData = UIImageJPEGRepresentation(image, 1)
let relativePath = imgName
let path = self.documentsPathForFileName(name: relativePath)
do {
try imageData?.write(to: path, options: .atomic)
} catch {
return false
}
return true
}
func readFile(_ name: String) -> UIImage{
let fullPath = self.documentsPathForFileName(name: name)
var image = UIImage()
if FileManager.default.fileExists(atPath: fullPath.path){
image = UIImage(contentsOfFile: fullPath.path)!
}else{
image = UIImage(named: "user")! //a default place holder image from apps asset folder
}
return image
}
}
extension ReadWriteFileFS{
func documentsPathForFileName(name: String) -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let path = paths[0]
let fullPath = path.appendingPathComponent(name)
return fullPath
}
}
Swift 4.x
Xcode 11.x
func saveImageInUserDefault(img:UIImage, key:String) {
UserDefaults.standard.set(img.pngData(), forKey: key)
}
func getImageFromUserDefault(key:String) -> UIImage? {
let imageData = UserDefaults.standard.object(forKey: key) as? Data
var image: UIImage? = nil
if let imageData = imageData {
image = UIImage(data: imageData)
}
return image
}