【问题标题】:How do I get a thumbnail or saveable path from UIImagePickerController to use for a UIImageView?如何从 UIImagePickerController 获取缩略图或可保存路径以用于 UIImageView?
【发布时间】:2011-06-07 11:23:25
【问题描述】:

有人可以解释或展示一些示例代码,说明在用户使用 UIImagePickerController 选择照片后如何使用获取要放入 UIImageView 的缩略图?

假设我想将缩略图设置为表格视图单元格的图像。当用户按下单元格时,会显示图像选择器,并且用户选择设备上已经存在的图像。我还想保存该缩略图的路径,以便下次显示视图时,可以显示正确的缩略图。

我能够显示图像选择器,并且我的代表正确获取了所选图像,但我想要缩略图的路径,并且我想使用该路径加载缩略图(即我想保存路径)。 我今天已经搜索了几个小时,还没有弄清楚。也许我不了解 ALAsset,或者可能是别的东西,但我找不到任何对我有帮助的例子。我以前从未使用过图像选择器或 ALAsset,所以我对此完全陌生。

【问题讨论】:

    标签: iphone uiimageview uiimage uiimagepickercontroller alasset


    【解决方案1】:

    保存 URL 可能会出现问题:

    1. 至少在 iOS 4.x 中,不能保证 URL 是唯一的。如果用户删除/添加图片,它们可以重复使用,这显然很常见。所以,你保留的网址将来可以指向不同的图片!
    2. 当用户更新到 iOS 5 时,URL 不再有效。啊!!!苹果已经重写了照片库,没有向后兼容性。

    【讨论】:

      【解决方案2】:

      //如果您正在阅读本文并查看下面的 cmets 并认为 ??WTF??这是因为我正在编辑我的原始答案而不是发布两个答案,希望事情会更干净。重要的是要知道 ALAssetsLibrary 是 iOS 4.x 的东西。

      下面的代码将用于获取资源库 URL,然后从缩略图表示中生成 UIImage。尽管我直接使用资产库 url,但没有理由不能通过将字符串表示形式转换为 NSURL 来满足imageURL 分配的相同代码。免责声明:此代码可能会泄漏或更糟,但它回答了原始发布者的问题,并希望具有价值。

      下面的代码大量借鉴了 this Stack Overflow question,它基本上涵盖了相同的主题。除了这里的代码,我还包含了 AssetsLibrary.framework 和另一个问题中引用的 ALAssetsLibrary 类型定义。

      整个技巧是您不能直接从资产库中引用 NSURL。我认为(尽管我不知道)它以某种方式引用了数据存储而不是文件,因此从 URL 返回的数据不是直接的 NSData,因此您不能以旧方式使用它。

      代码中有一个 UIImageView,叫做photo。希望其他一切都很容易弄清楚。

      - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
          NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
          NSLog(@"%@",imageURL);
          ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
          {
              CGImageRef iref = [myasset thumbnail];
              if (iref) {
                  UIImage *theThumbnail = [UIImage imageWithCGImage:iref];
                  [[self photo] setImage:theThumbnail];
      
              }
          };
      
      
          ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
          {
              NSLog(@"booya, cant get image - %@",[myerror localizedDescription]);
          };
      
          if(imageURL)
          {
              ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
              [assetslibrary assetForURL:imageURL 
                             resultBlock:resultblock
                            failureBlock:failureblock];
          }
      
          [self dismissModalViewControllerAnimated:YES];
      }
      

      如果您不想要缩略图但想要完整的照片,您只需将 AssetForURLResult 块中的代码更改为如下所示:

             ALAssetRepresentation *rep = [myasset defaultRepresentation];
          CGImageRef iref = [rep fullResolutionImage];
      

      我们可以把这个练习留给用户。

      祝你好运,希望这有助于你解决问题。

      【讨论】:

      • 如果用户从相机胶卷中删除图像,这不会有问题,我视图中的图片将保持空白。图片对于视图的其余部分不是必需的。
      • 图片对于其他视图不是必需的。我的目标是 IOS 4.0 及更高版本。为方便起见,假设我想将全尺寸图像放入 UIImageView。如果我只有 info 字典中的 NSURL 对象,我该怎么做?到目前为止我尝试过的东西都没有奏效,我想我错过了一些明显的东西。
      • NSURL 对象将指向图像,然后您可以下载它。由于您的目标是 IOS 4.0,因此您可以选择访问资产库本身。 iCode 博客 (icodeblog.com/2010/07/08/asset-libraries-and-blocks-in-ios-4) 上有一个教程,但也许您已经看过了?一旦你掌握了资产,你可以使用 valueForPropery 方法并获取 ALAssetPropertyURLs,它是一个包含文件 URL 的字典。
      • 当我从图像选择器结果中获取 NSURL 对象并在调试时将鼠标悬停在该对象上时,它会打印为“assets-library://asset/asset.JPG?id=10000000002&ext= JPG”。如果我使用 dataWithContentsOfURL:chosenPictureNSURL 创建一个 NSData 对象,它会失败。我已经看过你链接的教程,但我不明白如何使用资产库来获取一张图片,搜索时也找不到任何示例。感谢您迄今为止的帮助!
      【解决方案3】:

      我现在已经大致弄清楚了。我遇到的困难是理解 Blocks,主要是 Blocks 的语法让我很难理解它们是什么以及它们是如何工作的。

      在 UIImagePickerController 的委托中,当用户选择了一张图片时,您可以使用以下方法获取资源库中图片的路径:

      NSURL *path = [info objectForKey:UIImagePickerControllerReferenceURL];
      

      使用该对象,您可以使用以下代码获取完整大小的图像或缩略图:

      ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
      {
          ALAssetRepresentation *rep = [myasset defaultRepresentation];
          CGImageRef iref = [rep fullResolutionImage];
          if (iref) {
              // Gets the full size image
              self.fullSizeImage = [UIImage imageWithCGImage:iref];
          }
      
          // Gets the thumbnail
          self.thumbnail = [UIImage imageWithCGImage:[myasset thumbnail]];
      };
      
      ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
      {
          NSLog(@"in failureblock, got an error: %@",[myerror localizedDescription]);
      };
      
      ALAssetsLibrary *assetsLib = [[ALAssetsLibrary alloc] init];
      [assetsLib assetForURL:urlForImage resultBlock:resultblock failureBlock:failureblock];
      

      这个页面真的帮助我理解了 Blocks:Blocks in iOS 4
      另见display image from URL retrieved from ALAsset in iPhone

      【讨论】:

        【解决方案4】:

        您可以将您从 imagePicker 中选择的图像保存到文档目录中,而不是从选择器中引用它 这是可用于保存图像的代码。在用户从选择器中选择照片时调用的回调方法中实现该方法

         NSFileManager   fileManager    = [NSFileManager defaultManager];
        
            NSArray*  output_PDF_paths  =  NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        
            NSString* output_PDF_documentsDirectory = [output_PDF_paths objectAtIndex:0];
            NSString* output_PDF_ABSOLUTE_PATH  = [output_PDF_documentsDirectory stringByAppendingPathComponent:@"ImageName.png"];  
        
            BOOL success_new = [UIImagePNGRepresentation(ProfilePhotoselected) writeToFile:previewPagePath atomically:YES];
        

        //这里的“ProfilePhotoselected”是您从选取器中获取的图像,作为您的 callabck 方法中的参数

        【讨论】:

        • 这是一种方法,但问题是我还必须实现可以从不再使用的文档目录中删除图片的代码,更不用说它只需要更多空间。理想情况下,我希望图片只存储在相机胶卷中,如果用户从那里删除图像,没什么大不了的,我的代码不会显示图像。
        猜你喜欢
        • 2017-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-01
        • 2012-03-05
        • 2011-12-14
        • 1970-01-01
        • 2013-08-13
        相关资源
        最近更新 更多