web-dev-qa-db-ja.com

IOSのUIViewからアプリケーションドキュメントフォルダーに画像を保存する

ユーザーが画像を保存できるようになるまで保持できるUIImageViewがあります。問題は、ビューに配置した画像を実際に保存および取得する方法がわからないことです。

次のように画像を取得してUIImageViewに配置しました。

//Get Image 
- (void) getPicture:(id)sender {
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.allowsEditing = YES;
    picker.sourceType = (sender == myPic) ? UIImagePickerControllerSourceTypeCamera : UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    [self presentModalViewController:picker animated:YES];
    [picker release];
}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage (UIImage *)image editingInfo:(NSDictionary *)editingInfo {
    myPic.image = image;
    [picker dismissModalViewControllerAnimated:YES];
}

UIImageViewで選択した画像を表示しますが、保存方法がわかりません。ビューの他のすべての部分(主にUITextfield)をCore Dataに保存しています。私は検索して検索し、人々が示唆した多くのコードを試しましたが、コードを正しく入力していないか、コードが設定されている方法でそれらの提案が機能しません。おそらく前者です。 UITextFieldsにテキストを保存するために使用しているのと同じアクション(保存ボタン)を使用して、UIImageViewに画像を保存したいと思います。 UITextField情報を保存する方法は次のとおりです。

// Handle Save Button
- (void)save {

    // Get Info From UI
    [self.referringObject setValue:self.myInfo.text forKey:@"myInfo"];

前に言ったように、これを機能させるためにいくつかの方法を試しましたが、理解することはできません。私の人生で初めて、無生物に物理的な危害を与えたかったのですが、どうにかして自分を抑えることができました。

ユーザーがアプリケーションのドキュメントフォルダーのUIImageViewに配置した画像を保存し、ユーザーがそのビューをスタックにプッシュしたときに表示するために、それを取得して別のUIImageViewに配置できるようにしたいと思います。どんな助けも大歓迎です!

110
forgot

それはすべて良いです、男。自分や他人を傷つけないでください。

データセットが大きくなりすぎるとパフォーマンスに影響する可能性があるため、これらのイメージをCore Dataに保存することはおそらくないでしょう。画像をファイルに書き込む方が良い。

NSData *pngData = UIImagePNGRepresentation(image);

これにより、キャプチャした画像のPNGデータが取り出されます。ここから、ファイルに書き込むことができます:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory 
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"image.png"]; //Add the file name
[pngData writeToFile:filePath atomically:YES]; //Write the file

後で読むことも同じように機能します。上記で行ったようにパスを作成し、次に:

NSData *pngData = [NSData dataWithContentsOfFile:filePath];
UIImage *image = [UIImage imageWithData:pngData];

あなたがたぶんやりたいことは、あなたのためにパス文字列を作成するメソッドを作ることです、あなたはそのコードがどこにでも散らばるのを望まないので。次のようになります。

- (NSString *)documentsPathForFileName:(NSString *)name
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);  
    NSString *documentsPath = [paths objectAtIndex:0];

    return [documentsPath stringByAppendingPathComponent:name]; 
}

お役に立てば幸いです。

336
Danilo Campos

Swift 3.0バージョン

let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString

let img = UIImage(named: "1.jpg")!// Or use whatever way to get the UIImage object
let imgPath = URL(fileURLWithPath: documentDirectoryPath.appendingPathComponent("1.jpg"))// Change extension if you want to save as PNG

do{
    try UIImageJPEGRepresentation(img, 1.0)?.write(to: imgPath, options: .atomic)//Use UIImagePNGRepresentation if you want to save as PNG
}catch let error{
    print(error.localizedDescription)
}
3
Fangming

これは Fangming Ningの答えSwift 4.2で、 推奨などSwifty method ドキュメントディレクトリパスを取得し、ドキュメントを改善します。新しい方法に対するFangming Ningの功績。

guard let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
    return
}

//Using force unwrapping here because we're sure "1.jpg" exists. Remember, this is just an example.
let img = UIImage(named: "1.jpg")!

// Change extension if you want to save as PNG.
let imgPath = documentDirectoryPath.appendingPathComponent("1.jpg")

do {
    //Use .pngData() if you want to save as PNG.
    //.atomic is just an example here, check out other writing options as well. (see the link under this example)
    //(atomic writes data to a temporary file first and sending that file to its final destination)
    try img.jpegData(compressionQuality: 1)?.write(to: imgPath, options: .atomic)
} catch {
    print(error.localizedDescription)
}

ここで可能なすべてのデータ書き込みオプションを確認してください。

1
Tamás Sengel
#pragma mark == Save Image To Local Directory

-(void)saveImageToDocumentDirectoryWithImage: (UIImage *)capturedImage {
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"/images"];

//Create a folder inside Document Directory
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
    [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder

NSString *imageName = [NSString stringWithFormat:@"%@/img_%@.png", dataPath, [self getRandomNumber]] ;
// save the file
if ([[NSFileManager defaultManager] fileExistsAtPath:imageName]) {
    // delete if exist
    [[NSFileManager defaultManager] removeItemAtPath:imageName error:nil];
}

NSData *imageDate = [NSData dataWithData:UIImagePNGRepresentation(capturedImage)];
[imageDate writeToFile: imageName atomically: YES];
}

#pragma mark
#pragma mark == Generate Random Number
-(NSString *)getRandomNumber{
NSTimeInterval time = ([[NSDate date] timeIntervalSince1970]); // returned as a double
long digits = (long)time; // this is the first 10 digits
int decimalDigits = (int)(fmod(time, 1) * 1000); // this will get the 3 missing digits
//long timestamp = (digits * 1000) + decimalDigits;
NSString *timestampString = [NSString stringWithFormat:@"%ld%d",digits ,decimalDigits];
return timestampString;
}
0
Mannam Brahmam

Swiftの場合:

let paths: [NSString?] = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .LocalDomainMask, true)
if let path = paths[0]?.stringByAppendingPathComponent(imageName) {
    do {
        try UIImagePNGRepresentation(image)?.writeToFile(path, options: .DataWritingAtomic)
    } catch {
        return
    }
}
0
NatashaTheRobot