Lưu hình ảnh vào thư mục tài liệu ứng dụng từ UIView trên iOS


114

Tôi có một UIImageView cho phép người dùng đặt và giữ một hình ảnh cho đến khi nó có thể được lưu. Vấn đề là, tôi không thể tìm ra cách thực sự lưu và truy xuất hình ảnh mà tôi đã đặt trong chế độ xem.

Tôi đã truy xuất và đặt hình ảnh trong UIImageView như sau:

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

Nó hiển thị hình ảnh đã chọn trong UIImageView của tôi rất tốt, nhưng tôi không biết làm cách nào để lưu nó. Tôi đang lưu tất cả các phần khác của chế độ xem (chủ yếu là UITextfield) trong Dữ liệu cốt lõi. Tôi đã tìm kiếm và tìm kiếm và thử nhiều bit mã mà mọi người đã đề xuất, nhưng tôi nhập mã không chính xác hoặc những đề xuất đó không hoạt động với cách tôi thiết lập mã của mình. Nó có thể là trước đây. Tôi muốn lưu hình ảnh trong UIImageView bằng hành động tương tự (nút lưu) mà tôi đang sử dụng để lưu văn bản trong UITextFields. Đây là cách tôi lưu thông tin UITextField của mình:

// Handle Save Button
- (void)save {

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

Giống như tôi đã nói trước đó, tôi đã thử một số phương pháp để làm cho nó hoạt động, nhưng không thể hiểu được nó. Lần đầu tiên trong đời tôi muốn gây tổn hại về thể chất cho một vật vô tri vô giác, nhưng tôi đã kiềm chế được.

Tôi muốn có thể lưu hình ảnh mà người dùng đặt vào UIImageView trong thư mục tài liệu của ứng dụng, sau đó có thể truy xuất nó và đặt nó trong một UIImageView khác để hiển thị khi người dùng đẩy chế độ xem đó vào ngăn xếp. Bất kỳ trợ giúp nào cũng được đánh giá rất cao!

Câu trả lời:


341

Tất cả đều tốt, anh bạn. Đừng làm hại bản thân hoặc người khác.

Bạn có thể không muốn lưu trữ những hình ảnh này trong Dữ liệu cốt lõi, vì điều đó có thể ảnh hưởng đến hiệu suất nếu tập dữ liệu phát triển quá lớn. Tốt hơn để ghi hình ảnh vào tệp.

NSData *pngData = UIImagePNGRepresentation(image);

Thao tác này sẽ lấy ra dữ liệu PNG của hình ảnh bạn đã chụp. Từ đây, bạn có thể ghi nó vào một tệp:

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

Đọc nó sau đó hoạt động theo cùng một cách. Xây dựng đường dẫn như chúng ta vừa làm ở trên, sau đó:

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

Những gì bạn có thể muốn làm là tạo một phương thức tạo chuỗi đường dẫn cho bạn, vì bạn không muốn mã đó rải rác khắp nơi. Nó có thể trông như thế này:

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

    return [documentsPath stringByAppendingPathComponent:name]; 
}

Hy vọng điều đó hữu ích.


2
hoàn toàn chính xác - Just Wanna đề cập đến Hướng dẫn lưu trữ của Apple nên tuỳ theo tính chất của hình ảnh, nó nên được lưu trữ dưới Caches
Daij-Đan

Tôi đã làm theo đề xuất và mã của bạn. nhưng nó không xuất hiện trong các phần ảnh. Làm sao chuyện này lại xảy ra?
NovusMobile

@DaniloCampos Làm cách nào để tạo một thư mục bên trong Thư mục Tài liệu và sau đó lưu tệp bên trong thư mục đó?
Pradeep Reddy Kypa

3

Phiên bản 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)
}

2

Đây là câu trả lời của Fangming Ning cho Swift 4.2 , được cập nhật với một phương pháp Swifty được khuyến nghị và nhiều hơn để truy xuất đường dẫn thư mục tài liệu và với tài liệu tốt hơn. Tín dụng cho Fangming Ning cho phương pháp mới.

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

Kiểm tra tất cả các tùy chọn ghi dữ liệu có thể có tại đây.


Điều này có chính xác? Trong một câu trả lời cho một câu hỏi khác ở đây, tôi thấy rằng fileURLWithPathcùng với absoluteStringlà sai.
câm vào

@dumbledad Cảm ơn bạn đã cung cấp thông tin, tôi đã cập nhật câu trả lời của mình và viết lại mã cho Swift 4.2.
Tamás Sengel

2
#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 - 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;
}

1

Swift 4 với phần mở rộng

extension UIImage{

func saveImage(inDir:FileManager.SearchPathDirectory,name:String){
    guard let documentDirectoryPath = FileManager.default.urls(for: inDir, in: .userDomainMask).first else {
        return
    }
    let img = UIImage(named: "\(name).jpg")!

    // Change extension if you want to save as PNG.
    let imgPath = URL(fileURLWithPath: documentDirectoryPath.appendingPathComponent("\(name).jpg").absoluteString)
    do {
        try UIImageJPEGRepresentation(img, 0.5)?.write(to: imgPath, options: .atomic)
    } catch {
        print(error.localizedDescription)
    }
  }
}

Ví dụ sử dụng

 image.saveImage(inDir: .documentDirectory, name: "pic")

0

Trong 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
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.