【问题标题】:iPhone Save image to documents folder task in background threadiPhone在后台线程中将图像保存到文档文件夹任务
【发布时间】:2012-08-17 08:55:23
【问题描述】:

我对 iOS 编程很陌生。我一直在开发一个非常简单的相机应用程序,但我需要完成的一个主要功能是不仅要显示使用内置相机拍摄的图像或使用 UIImageView 从 iPhone 画廊中挑选的图像,还要将其保存到文档文件夹,以便稍后在第二个视图控制器中调用它。我已经通过以下代码成功完成了这项工作:

    //Save taken image to Camera Roll and display on UIImageView
    -(void)imagePickerController:(UIImagePickerController *)pickerdidFinishPickingMediaWithInfo:(NSDictionary *)info{

NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];

[self dismissModalViewControllerAnimated:YES];


if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {


    UIImage *image = [info 
                      objectForKey:UIImagePickerControllerOriginalImage];


    imageView.image = image;
    imageView.hidden = NO;

    if (newMedia)
        UIImageWriteToSavedPhotosAlbum(image, 
                                       self,
                                       @selector(image:finishedSavingWithError:contextInfo:),
                                       nil);
}
    //Save photo to documents folder
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:@"savedImage.png"];
UIImage *image = imageView.image; // imageView is my image from camera
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:NO];
}}

我遇到的问题是将图像保存到文档文件夹的过程需要很长时间(> 5 秒!),以至于用户会认为应用程序挂起。当然我想显示一个活动指示器,但现在知道这是不可能的,因为保存到文档文件夹任务占用了我的主线程,因此阻止任何其他 UIView 任务执行,直到保存完成。

似乎解决方案正在将保存到文档任务转移到后台线程,但目前我无法完全理解如何做到这一点。有谁知道我可以添加到上述代码中以将此任务移至后台的一些简单代码?或者也许有人可以向我推荐一个很好的教程?

编辑:

这是我尝试过的其他方法。我已经设置了 @jake_hetfield 的 saveImage 方法,并将保存到文档的代码放在里面,如下所示:

    - (void)saveImage:(UIImage*)image {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,        
    NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *savedImagePath = [documentsDirectory       
    stringByAppendingPathComponent:@"savedImage.png"];
    UIImage *image = imageView.image; // imageView is my image from camera
    NSData *imageData = UIImagePNGRepresentation(image);
    [imageData writeToFile:savedImagePath atomically:NO];

    [self performSelectorInBackground:@selector(saveImage:) withObject:image]; }

但是这行 UIImage *image = imageView.image;突然返回构建错误“重新定义图像”。这很令人困惑,因为当我在 PickerDidFinish... 方法中运行保存到文档代码时,同一行仍然有效。关于如何解决此错误的任何想法?

提前致谢!

【问题讨论】:

  • 您正在重新定义变量图像。您应该删除行 UIImage *image = imageView.image;而是在您进行调用时将您的图像作为方法的参数发送或删除方法 saveImage 的输入参数图像。在同一个方法中不能有两个名为 image 的变量。请参阅我编辑的答案。

标签: ios background camera xcode4.4 background-thread


【解决方案1】:

创建一个保存图片的方法,然后使用performSelectorInBackground调用它,它会在后台运行。

例子:

- (void)saveImage:(UIImage*)image{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    // Code for saving image here    

    [pool release];
}

这样称呼它:

/* ... */

[self performSelectorInBackground:@selector(saveImage:) withObject:imageView.image];

/* ...*/

【讨论】:

  • 感谢您的回答!但我仍然有麻烦。我尝试在保存到 docs 文件夹的代码之前添加 saveImage 方法(在 NSArray *paths 等之前)。不知何故 Xcode 不喜欢这样,告诉我“saveImage”未声明。我只能通过将 saveImage 方法更早地放在 PickerDidFinishPicking 方法之前来消除该错误,然后在我的保存到文档代码的底部调用它。这构建并运行良好,但保存任务仍然阻止我的活动指示器显示。你知道我做错了什么吗?
  • 您必须在您的类声明中的头文件 (.h) 中声明该方法,然后您可以在您的 .m 文件中的类实现中任意添加它。听起来你没有关于如何在 Objective-C 中创建类和方法的基础知识。我建议您在玩后台任务之前先练习基础知识并更好地学习语法。
  • 我稍微改变了答案,我现在将 imageView.image 作为参数发送
猜你喜欢
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-17
  • 2016-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多