Збережіть зображення в папці документів програми з UIView на IOS


114

У мене є 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) я зберігаю в основних даних. Я шукав і шукав, і випробував багато бітів коду, які запропонували люди, але я не ввожу код правильно, або ці пропозиції не працюють з тим, як я налаштував свій код. Ймовірно, колишній. Я б хотів зберегти зображення в UIImageView за допомогою тієї ж дії (кнопка збереження), яку я використовую для збереження тексту в полях UITextFields. Ось як я зберігаю свою інформацію про UITextField:

// Handle Save Button
- (void)save {

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

Як я вже говорив раніше, я спробував кілька методів, щоб змусити це працювати, але не можу зрозуміти це. Вперше в житті я хотів завдати фізичної шкоди неживому предмету, але мені вдалося стримати себе.

Я хотів би мати можливість зберегти зображення, яке користувач поміщає в UIImageView у папці документів програми, а потім зможу отримати його та помістити в інший UIImageView для відображення, коли користувач натисне цей погляд на стек. Будь-яка допомога дуже вдячна!

Відповіді:


341

Все добре, чоловіче. Не шкодите ні собі, ні іншим.

Напевно, ви не хочете зберігати ці зображення в основних даних, оскільки це може вплинути на продуктивність, якщо набір даних зросте занадто великим. Краще записати зображення у файли.

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

Сподіваюся, це корисно.


2
цілком правильно - просто хочеться згадати Правила зберігання Apple, так що ВЗАЄМО з природою зображень, вони повинні зберігатися під
кешами

Я дотримувався вашої пропозиції та коду. але це не відображається у розділах фотографій. Як це сталося?
NovusMobile

@DaniloCampos Як створити папку в каталозі документів, а потім зберегти файл у цій папці?
Pradeep Reddy Kypa

3

Версія 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

Це відповідь Fangming Ning для Swift 4.2 , оновлена рекомендованим і більш швидким методом Swifty для отримання шляху до каталогу директорій та з кращою документацією. Кредити 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)
}

Ознайомтесь з усіма можливими варіантами запису даних тут.


Це правильно? У відповіді на інше запитання тут я виявив, що fileURLWithPathразом з absoluteStringневірно.
dumbledad

@dumbledad Дякую за інформацію, я оновив свою відповідь і також написав код для Swift 4.2.
Тамас Сенгель

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 з розширенням

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

Приклад використання

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

0

У Свіфті:

let paths: [NSString?] = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .LocalDomainMask, true)
if let path = paths[0]?.stringByAppendingPathComponent(imageName) {
    do {
        try UIImagePNGRepresentation(image)?.writeToFile(path, options: .DataWritingAtomic)
    } catch {
        return
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.