Отображать изображение из URL, полученного из ALAsset в iPhone

Я использую ALAsset Framework для доступа к файлам в галерее устройств.

До сих пор я могу получить доступ к миниатюре и отобразить ее.
Я хочу отобразить фактическое изображение в представлении изображения, но я не могу понять, как это сделать.

Я попытался использовать поле URL в объекте ALAsset, но не увенчался успехом.

Кто-нибудь знает, как это можно сделать?

Вот некоторый код, где мне удалось получить доступ к миниатюре и поместить его в ячейку таблицы:

- (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;
}

Ответ 1

API немного изменил правила, и вы больше не получаете прямой доступ к файловой системе в библиотеку iPhoto. Вместо этого вы получаете URL-адрес библиотеки ресурсов.

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

Вы используете объект ALAssetLibrary для доступа к объекту ALAsset через URL.

поэтому из документов для 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 возвращает resultblock не будет запущен как его обратный вызов. Настолько 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

и comme cá

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

Ответ 2

Уоррен ответил хорошо для меня. Одной из полезных вещей для некоторых людей является одновременное включение ориентации изображения и масштабных метаданных. Вы делаете это в своем блоке результатов следующим образом:

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]];

Один трюк, который следует отметить, заключается в том, что если вы используете [rep fullScreenImage] вместо [rep fullResolutionImage] на iOS 5, вы получаете изображение, которое уже повернуто - оно, однако, находится в разрешении экрана iPhone, то есть оно имеет более низкое разрешение.

Ответ 3

Просто, чтобы объединить ответы Уоррена и 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.
}];

Мне лично нравится устанавливать failureBlock на nil.

Ответ 4

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

просто предоставите UIReferenceURl, который вы получили для изображения в фотобиблиотеке, приведенной выше... его просто отлично работает.,. Я сделал это в

  • Ячейка UIcollectionView

    .. если вы просто хотите отобразить его в

  • UIImageView

    означает

Изменить

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

Для

imageView.image = copyOfOriginalImage;