web-dev-qa-db-ja.com

iPhoneのALAssetから取得したURLの画像を表示します

デバイスのフォトギャラリー内のファイルにアクセスするためにALAsset Frameworkを使用しています。

これまでのところ、サムネイルにアクセスして表示することができます。
実際の画像を画像ビューに表示したいのですが、どうすればよいかわかりません。

ALAssetオブジェクトのURLフィールドを使用しようとしましたが、失敗しました。

誰もがこれをどのように行うことができるか知っていますか?

サムネイルにアクセスし、それをテーブルセルに配置できるコードを次に示します。

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {


  static NSString *CellIdentifier = @"Cell";

  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
  }
  //here 'asset' represents the ALAsset object


  asset = [assets objectAtIndex:indexPath.row];
       //i am accessing the thumbnail here
  [cell.imageView setImage:[UIImage imageWithCGImage:[asset thumbnail]]];
  [cell.textLabel setText:[NSString stringWithFormat:@"Photo %d", indexPath.row+1]];

  return cell;
}
66
Bangdel

APIによってルールがわずかに変更され、iPhotoライブラリへの直接のファイルシステムアクセスができなくなりました。代わりに、このようなアセットライブラリのURLを取得します。

assets-library://asset/asset.JPG?id=1000000003&ext=JPG

ALAssetLibraryオブジェクトを使用して、URLを介してALAssetオブジェクトにアクセスします。

aLAssetLibraryのドキュメントから、これをヘッダー(またはソース)にスローします

typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);

これは厳密には必要ありませんが、物事をきれいに保ちます。
そしてソースで。

-(void)findLargeImage
{
    NSString *mediaurl = [self.node valueForKey:kVMMediaURL];

    //
    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        CGImageRef iref = [rep fullResolutionImage];
        if (iref) {
            largeimage = [UIImage imageWithCGImage:iref];
            [largeimage retain];
        }
    };

    //
    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
        NSLog(@"booya, cant get image - %@",[myerror localizedDescription]);
    };

    if(mediaurl && [mediaurl length] && ![[mediaurl pathExtension] isEqualToString:AUDIO_EXTENSION])
    {
        [largeimage release];
        NSURL *asseturl = [NSURL URLWithString:mediaurl];
        ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
        [assetslibrary assetForURL:asseturl 
                       resultBlock:resultblock
                      failureBlock:failureblock];
    }
}

留意すべき点は、iOS4の移植を開始する前に私にとっては新しいブロックを使用していることですが、

https://www.mikeash.com/pyblog/friday-qa-2008-12-26.html

そして

https://developer.Apple.com/library/content/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html

彼らはあなたの頭を少し曲げますが、通知セレクターまたはコールバックと考えれば、それは一種の助けになります。

また

  • findLargeImageが返されるとき、コールバックとしてまだ実行されていない結果ブロックを返します。したがって、largeImageはまだ有効ではありません。
  • largeImageは、メソッドのスコープ外のインスタンス変数である必要があります。

このコンストラクトを使用してメソッドを使用するときにこれを行いますが、使用に適したものが見つかる場合があります。

[node.view findLargeImage];
UIImage *thumb = node.view.largeImage;
if (thumb) { blah blah }

とにかくこれを機能させようとしている間に学んだことです。

iOS 5アップデート

IOS5およびシングルコアデバイスでは、結果ブロックの起動が少し遅いように思えるので、findLargeImageを呼び出した後に直接利用できる画像に頼ることはできませんでした。それで、デリゲートを呼び出すように変更しました。

@protocol HiresImageDelegate <NSObject>
@optional
-(void)hiresImageAvailable:(UIImage *)aimage;
@end

そしてcommecá

//
    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        CGImageRef iref = [rep fullResolutionImage];
        if (iref) {
            UIImage *largeimage = [UIImage imageWithCGImage:iref];
            [delegate hiresImageAvailable:large];
        }
    };
93
Warren Burton

ウォーレンの答えは私にとってはうまくいきました。一部の人々にとって有用なことの1つは、画像の方向とスケールのメタデータを同時に含めることです。次のように結果ブロックでこれを行います。

ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
    ALAssetRepresentation *rep = [myasset defaultRepresentation];
    CGImageRef iref = [rep fullResolutionImage];
    if (iref) 
    {
        UIImage *largeimage = [UIImage imageWithCGImage:iref scale:[rep scale] orientation:[rep orientation]];
        [delegate hiresImageAvailable:large];
    }
};

その場合のimageWIthCGImage呼び出しには、orientationを作成するときにスケールとUIImageが追加されます。

[UIImage imageWithCGImage:iref scale:[rep scale] orientation:[rep orientation]];

注意すべきトリックの1つは、[rep fullScreenImage] の代わりに [rep fullResolutionImage] iOS 5では、すでに回転された画像を取得します-ただし、iPhone画面の解像度です。つまり、より低い解像度です。

15
oknox

Warrenとoknoxの回答を短いスニペットにまとめるだけです。

ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary assetForURL:self.selectedPhotos[i] resultBlock: ^(ALAsset *asset){
    ALAssetRepresentation *representation = [asset defaultRepresentation];
    CGImageRef imageRef = [representation fullResolutionImage];
    if (imageRef) {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        imageView.image = [UIImage imageWithCGImage:imageRef scale:representation.scale orientation:representation.orientation];
        // ...
    }
} failureBlock: ^{
    // Handle failure.
}];

個人的にfailureBlocknilに設定するのが好きです。

9
Matthew Quiros
     NSURL* aURL = [NSURL URLWithString:@"URL here"];

     ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
     [library assetForURL:aURL resultBlock:^(ALAsset *asset)
     {
     UIImage  *copyOfOriginalImage = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage] scale:0.5 orientation:UIImageOrientationUp];

     cell.backgroundView = [[UIImageView alloc] initWithImage:copyOfOriginalImage];
     }
     failureBlock:^(NSError *error)
     {
     // error handling
     NSLog(@"failure-----");
     }];

上記で提供されたphotolibraryの画像用に取得したUIReferenceURlを提供するだけで...正常に機能します。 。で表示しました

  • UIcollectionViewセル

    ..だけで表示したい場合

  • UIImageView

    手段

変更

cell.backgroundView = [[UIImageView alloc] initWithImage:copyOfOriginalImage];

To

imageView.image = copyOfOriginalImage;
8
suku