отображать изображение с URL-адреса, полученного из ALAsset в iPhone - PullRequest
66 голосов
/ 01 октября 2010

Я использую 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;
}

Ответы [ 4 ]

93 голосов
/ 02 октября 2010

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 возвращает результат, блок еще не запустился как обратный вызов,Так что 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];
        }
    };
15 голосов
/ 24 января 2013

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

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 - то есть имеет более низкое разрешение.

9 голосов
/ 02 сентября 2013

Просто чтобы объединить ответы Уоррена и Окнокса в более короткий фрагмент:

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.

8 голосов
/ 19 сентября 2013
     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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...