将图像从 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 中。我搜索了又搜索,尝试了很多人们建议的代码,但要么是我没有正确地输入代码,要么是这些建议不适合我设置代码的方式。很可能是前者。我希望在 UIImageView 中使用与在 UITextFields 中保存文本相同的操作(一个保存按钮)来保存图像。下面是我如何保存我的 UITextField 信息:

// Handle Save Button
- (void)save {


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

正如我前面所说,我已经尝试了几种方法来使这个工作,但不能抓住它。有生以来第一次,我想对一个无生命的物体造成身体伤害,但是我设法克制住了自己。

I'd like to be able to save the image the user places into the UIImageView in the application's documents folder, and then be able to retrieve it and place it in another UIImageView for display when the user pushes that view onto the stack. Any help is greatly appreciated!

98584 次浏览

没事的,伙计,不要伤害自己和别人。

您可能不希望将这些映像存储在 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];
}

希望对你有帮助。

斯威夫特:

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

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

这是 方明宁的回答 斯威夫特4.2版,使用 推荐和更迅捷的方法进行更新,以检索文档目录路径,并使用更好的文档。这个新方法也要归功于方明宁。

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

点击这里查看所有可能的数据写入选项。

Swift 4 with extension

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")
#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;
}