如何保存UIImagePickerView Controller返回的图像

时间:2009-08-12 23:06:50

标签: iphone cocoa-touch

我有一个应用程序,用户将从UIImagePickerView中选择一个图像。

从中选择图像后,我想将其保存在我的应用程序中。

如何实现这一目标?

先谢谢你的帮助。

3 个答案:

答案 0 :(得分:4)

假设您使用的是SDK 3.0,这里有一些代码可以将图像保存到应用程序的文档文件夹中:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{   
    // Dismiss the picker
    [[picker parentViewController] dismissModalViewControllerAnimated:YES];

    // Get the image from the result
    UIImage* image = [info valueForKey:@"UIImagePickerControllerOriginalImage"];

    // Get the data for the image as a PNG
    NSData* imageData = UIImagePNGRepresentation(image);

    // Give a name to the file
    NSString* imageName = "MyImage.png";

    // Now, we have to find the documents directory so we can save it
    // Note that you might want to save it elsewhere, like the cache directory,
    // or something similar.
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* documentsDirectory = [paths objectAtIndex:0];

    // Now we get the full path to the file
    NSString* fullPathToFile = [documentsDirectory stringByAppendingPathComponent:imageName];

    // and then we write it out
    [imageData writeToFile:fullPathToFile atomically:NO];

    return;
}

答案 1 :(得分:3)

我会这样说:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
self.resumePreviousSettingAfterEditing = true;
[self.topImageView setImage:image];
[cubeModel setImage:image forFace:[cubeModel.validFaces objectAtIndex:selectedRowInFacePicker]];

[self dismissImagePickerAnimated:true];

}

您在控制器中注册一个事件来处理图像选择。在该事件处理程序中,在某处调用方法,比如在模型中设置新图像。该功能看起来像这样:

 (void)saveImage:(UIImage *)image withName:(NSString *)imageName {
    // get the image path
    NSString *filename = [self determineImagePath:imageName];

    // make sure the file is removed if it exists
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if([fileManager fileExistsAtPath:filename]) {
        if(NO == [fileManager removeItemAtPath:filename error:NULL]) {
        }
    }

    // Now, save the image to a file.
    if(NO == [UIImagePNGRepresentation(image) writeToFile:filename atomically:YES]) {
        [NSException raise:@"Image Save Failed" format:@"Unable to store image %s", filename]; 
    }
}

当你想再次加载图像时,你会这样:

- (UIImage *)loadImage:(NSString *)imageName {
    NSString *filename = [self determineImagePath:imageName];
    NSFileManager *fileManager = [NSFileManager defaultManager];

    self.currentImage = nil;
    if([fileManager fileExistsAtPath:filename]) {

        NSData *imageData = [[NSData alloc] initWithContentsOfFile:filename];
        UIImage *image = [UIImage imageWithData:imageData];

        self.currentImage = image;
    }
    return self.currentImage;
}

并且不要让我开始进行变革,这比应该变得更难。

享受, 雅各布

答案 2 :(得分:1)

保存UIImagePickerVIewController返回的图像时,您需要解决的一件事是将数据写入磁盘几乎总是慢得令人无法接受。在写入过程中,您的UI将挂起。因此,您应该始终在异步队列中执行这些类型的操作。即使测试时性能对于您的应用程序看起来足够好,您仍然应该执行异步队列 - 您永远不会知道设备可能进行的其他进程,这可能会减慢一次应用程序掌握在用户手中。

较新版本的iOS使用Grand Central Dispatch(GCD)可以非常轻松地异步保存照片。步骤是:

  1. 创建保存图片的NSBlockOperation
  2. 在块操作的完成块中,从磁盘&读取映像。显示它(这里唯一需要注意的是你必须使用主队列来显示图像:所有UI操作必须在主线程上进行)。
  3. 将块操作添加到操作队列并观察它!
  4. 就是这样。这是代码:

    // Grab the image
    UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
    
    // Create a block operation with our saves
    NSBlockOperation* saveOp = [NSBlockOperation blockOperationWithBlock: ^{
    
       [UIImagePNGRepresentation(image) writeToFile:file atomically:YES];
    
    }];
    
    // Use the completion block to update our UI from the main queue
    [saveOp setCompletionBlock:^{
    
       [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
    
          UIImage *image = [UIImage imageWithContentsOfFile:file];
          // TODO: Assign image to imageview
    
       }];
    }];
    
    // Kick off the operation, sit back, and relax. Go answer some stackoverflow
    // questions or something.
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:saveOp];
    

    一旦您对这种代码模式感到满意,您会发现自己经常使用它。它在生成大型数据集,加载时的长操作等方面非常有用。实际上,任何使UI偏差最小的操作都是此代码的良好候选者。请记住,当你不在主队列中时,你不能对UI做任何事情,其他一切都是蛋糕。