画像をNSUserDefaults
オブジェクトとして保存し、さらに使用するために取得することは可能ですか?
回答:
注意!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とxcode6のインストールプロセスの違いは、xcode6がxcodeで実行されるたびにアプリのUUIDを変更することです(パスの強調表示された部分:/ var / mobile / Containers / Data / Application / B0D49CF5-8FBE-4F14-87AE-FA8C16A678B1 / Documents / image.jpg)。
したがって、2つの回避策があります。
ボーナスとしてのコードの迅速なバージョンは次のとおりです(2番目のアプローチを使用):
データの書き込み:
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」のように好きなように呼び出すことができますか?
スイフト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")!
スイフト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...
}
用スウィフト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)!
アップルのドキュメントから、
NSUserDefaultsクラスは、float、double、integers、Booleans、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];
技術的には可能ですが、お勧めできません。代わりに、イメージをディスクに保存してください。NSUserDefaultsは、大きなバイナリデータファイルではなく、小さな設定を対象としています。
画像を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]];
この質問はグーグル検索インデックスが高いので、今日の日と年齢での@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
}
}
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
}