Сохранить изображение в папку документов приложений из UIView на IOS
У меня есть 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. Я искал и искал, и попробовал много фрагментов кода, которые люди предложили, но либо я не правильно вхожу в код, либо эти предложения не работают с тем, как я настроил свой код. Скорее всего, первое. Я хотел бы сохранить изображение в UIImageView с помощью того же действия (кнопка сохранения), которую я использую, чтобы сохранить текст в UITextFields. Вот как я сохраняю информацию UITextField:
// Handle Save Button
- (void)save {
// Get Info From UI
[self.referringObject setValue:self.myInfo.text forKey:@"myInfo"];
Как я уже говорил ранее, я попробовал несколько способов заставить это работать, но не могу понять. Впервые в жизни я хотел причинить физический вред неодушевленному объекту, но мне удалось сдержать себя.
Я хотел бы сохранить изображение, которое пользователь помещает в UIImageView в папку документов приложения, а затем сможет извлечь его и поместить в другой UIImageView для отображения, когда пользователь нажимает это представление на стек, Любая помощь очень ценится!
Ответы
Ответ 1
Все хорошо, мужик. Не наносите вред себе или другим.
Вероятно, вы не хотите хранить эти изображения в 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];
}
Надеюсь, что это поможет.
Ответ 2
версия 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
В 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
}
}
Ответ 4
Это ответ 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)
}
Проверьте все возможные варианты записи данных здесь.
Ответ 5
#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;
}
Ответ 6
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")