将图像保存在 NSUserDefaults 中?

发布于 2024-11-19 19:01:07 字数 51 浏览 1 评论 0原文

是否可以将图像作为对象保存到 NSUserDefaults 中,然后检索以供进一步使用?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

故事和酒 2024-11-26 19:01:07

要将图像保存在 NSUserDefaults 中:

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

要从 NSUserDefaults 检索图像:

NSData* imageData = [[NSUserDefaults standardUserDefaults] objectForKey:key];
UIImage* image = [UIImage imageWithData:imageData];

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];
浪荡不羁 2024-11-26 19:01:07

注意!如果您在 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)。

因此有 2 个解决方法:

  1. 跳过这个问题,因为一旦应用程序安装在真实设备上,它就永远不会更改 UUID(事实上它会更改,但它是新应用程序)
  2. 将相对路径保存到所需文件夹(在我们的例子中为应用程序的根目录)

这里是 swift代码版本作为奖励(使用第二种方法):

写入数据:

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
}

ATTENTION! IF YOU'RE WORKING UNDER iOS8/XCODE6 SEE MY UPDATE BELOW

For those who still looking for answer here is code of "advisable" way to save image in NSUserDefaults. You SHOULD NOT save image data directly into NSUserDefaults!

Write data:

// 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];

Read data:

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];
}

For iOS8/XCODE6
As tmr and DevC mentioned in comments below there is a problem with xcode6/ios8. The difference between xcode5 and xcode 6 installation process is that xcode6 changes apps UUID after each run in xcode (see hightlighted part in path: /var/mobile/Containers/Data/Application/B0D49CF5-8FBE-4F14-87AE-FA8C16A678B1/Documents/image.jpg).

So there are 2 workarounds:

  1. Skip that problem, as once app installed on real device it's never changes UUID (in fact it does, but it is new app)
  2. Save relative path to required folder (in our case to app's root)

Here is swift version of code as a bonus (with 2nd approach):

Write data:

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()

Read data:

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
}
路弥 2024-11-26 19:01:07

虽然可以将 UIImage 保存到 NSUserDefaults,但通常不推荐这样做,因为这不是保存图像的最有效方法;更有效的方法是将图像保存在应用程序的文档目录中。

出于此问题的目的,我已附上您问题的答案,以及保存 UIImage 的更有效方法。


NSUserDefaults(不推荐)

保存到 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 加载

此方法允许您从 NSUserDefaults 加载任何 UIImage

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

您可以这样称呼它:

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

更好的替代方法

保存到文档目录

此方法允许您将任何 UIImage 保存到应用内的文档目录

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

-(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 保存到设备的照片库,调用方式如下:

UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

将多个 UIImage 保存到照片库

此方法允许您将多个 UIImage 保存到设备的照片库

-(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是由UIImages组成的NSArray

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.

信愁 2024-11-26 19:01:07

对于 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")

在主VC中:

let bgImage = imageDefaults.imageForKey(key: "imageDefaults")!

For Swift 4

I almost tried everything in this question but no one is worked for me. and I found my solution.
first I created an extension for UserDefaults like below, then just called get and set methods.

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)
    } 
}

to set image as background in settingsVC I used code below.

let croppedImage = cropImage(selectedImage, toRect: rect, viewWidth: self.view.bounds.size.width, viewHeight: self.view.bounds.size.width)

imageDefaults.setImage(image: croppedImage, forKey: "imageDefaults")

in mainVC :

let bgImage = imageDefaults.imageForKey(key: "imageDefaults")!
指尖凝香 2024-11-26 19:01:07

对于 swift 2.2

存储:

NSUserDefaults.standardUserDefaults().setObject(UIImagePNGRepresentation(chosenImage), forKey: kKeyImage)

检索:

if let imageData = NSUserDefaults.standardUserDefaults().objectForKey(kKeyImage),
            let image = UIImage(data: imageData as! NSData){
            // use your image here...
}

For swift 2.2

To store:

NSUserDefaults.standardUserDefaults().setObject(UIImagePNGRepresentation(chosenImage), forKey: kKeyImage)

To retrieve:

if let imageData = NSUserDefaults.standardUserDefaults().objectForKey(kKeyImage),
            let image = UIImage(data: imageData as! NSData){
            // use your image here...
}
瀟灑尐姊 2024-11-26 19:01:07

是的,技术上可行

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

,但不建议,因为 plist 不适合存放大块二进制数据,尤其是用户首选项。最好将图像保存到用户文档文件夹并将对该对象的引用存储为 URL 或路径。

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.

西瑶 2024-11-26 19:01:07

对于Swift 3JPG格式

注册默认图像:

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)!

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)!
江挽川 2024-11-26 19:01:07

这在技术上是可行的,但不建议这样做。将图像保存到磁盘。 NSUserDefaults 适用于小型设置,而不是大型二进制数据文件。

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.

一枫情书 2024-11-26 19:01:07

从苹果文档来看,

NSUserDefaults 类提供了访问常见类型(例如浮点数、双精度数、整数、布尔值和 URL)的便捷方法。默认对象必须是属性列表,即 NSData、NSString、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];

From apple documentation,

The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Booleans, and URLs. A default object must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any other type of object, you should typically archive it to create an instance of NSData.

You can save image like this:-

[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation([UIImage imageNamed:@"yourimage.gif"])forKey:@"key_for_your_image"];

And read like this:-

 NSData* imageData = [[NSUserDefaults standardUserDefaults]objectForKey:@"key_for_your_image"];
    UIImage* image = [UIImage imageWithData:imageData];
泪意 2024-11-26 19:01:07

将图像保存到 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]];

Save image to 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]];

Load Image from 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]];
小巷里的女流氓 2024-11-26 19:01:07

是的,你可以使用。但由于它是用于存储首选项,因此您可以更好地将图像保存到文档文件夹中。

如果需要,您可以在 NSUserDefaults 中获取该路径。

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.

猛虎独行 2024-11-26 19:01:07

由于这个问题具有很高的谷歌搜索索引 - 这是@NikitaTook 在当今时代的答案,即 Swift 3 和 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
    }
}

Since this question has a high google search index - here's @NikitaTook's answer in today's day and age i.e. Swift 3 and 4 (with exception handling).

Note: This class is solely written to read and write images of JPG format to the filesystem. The Userdefaults stuff should be handled outside of it.

writeFile takes in the file name of your jpg image (with .jpg extension) and the UIImage itself and returns true if it is able to save or else returns false if it is unable to write the image, at which point you can store the image in Userdefaults which would be your backup plan or simply retry one more time. The readFile function takes in the image file name and returns a UIImage, if the image name passed to this function is found then it returns that image else it just returns a default placeholder image from the app's asset folder (this way you can avoid nasty crashes or other weird behaviors).

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
    }
}
时常饿 2024-11-26 19:01:07

斯威夫特 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
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文