web-dev-qa-db-fra.com

image d'affichage de l'URL extraite d'ALAsset sur iPhone

J'utilise un framework ALAsset pour accéder aux fichiers de la galerie de photos du périphérique.

Jusqu'à présent, je peux accéder à la vignette et l'afficher.
Je souhaite afficher l'image réelle dans une vue d'image, mais je ne parviens pas à comprendre comment faire.

J'ai essayé d'utiliser le champ URL de l'objet ALAsset mais cela a échoué.

Quelqu'un sait comment cela peut être fait?

Voici un code où j'ai pu accéder à la vignette et la placer dans une cellule de tableau:

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

L'API a légèrement modifié les règles et vous n'obtenez plus d'accès direct au système de fichiers à la bibliothèque iPhoto. Au lieu de cela, vous obtenez l'URL de la bibliothèque d'actifs comme ceci.

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

Vous utilisez l'objet ALAssetLibrary pour accéder à l'objet ALAsset via l'URL.

donc, dans la documentation d'ALAssetLibrary, insérez ceci dans un en-tête (ou votre source).

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

ce qui n'est pas strictement nécessaire mais garde les choses jolies.
et ensuite dans votre source.

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

Quelques points à noter sont que cela utilise des blocs qui étaient nouveaux pour moi avant que je commence à porter mon portage iOS4, mais vous aimerez peut-être regarder

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

et

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

Ils vous penchent un peu la tête, mais si vous les considérez comme des sélecteurs de notification ou des rappels, cela aide en quelque sorte.

Également

  • quand findLargeImage retourne le resultblock qui n’a pas encore été exécuté car c’est un rappel. Si grande, l'image ne sera pas encore valide.
  • largeImage doit être une variable d'instance non limitée à la méthode.

J'utilise cette construction pour faire cela en utilisant la méthode, mais vous pouvez trouver quelque chose de plus approprié à votre utilisation.

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

C’est ce que j’ai appris en essayant de faire fonctionner ça quand même.

Mise à jour iOS 5

Lorsque le bloc de résultats se déclenche semble être un peu plus lent avec iOS5 et peut-être des périphériques à un seul noyau, je ne pouvais donc pas compter sur l'image pour être disponible directement après avoir appelé findLargeImage. Je l'ai donc changé pour appeler un délégué.

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

et comme cá

//
    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

La réponse de Warren a bien fonctionné pour moi. Une chose utile pour certaines personnes consiste à inclure l'orientation de l'image et les métadonnées d'échelle en même temps. Vous faites cela dans votre bloc de résultats comme ceci:

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

L'appel imageWIthCGImage dans ce cas a une échelle et orientation ajouté lorsqu'il crée un UIImage pour vous.

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

Une astuce à noter est que si vous utilisez [rep fullScreenImage] au lieu de [rep fullResolutionImage] sur iOS 5, vous obtenez une image déjà pivotée - elle est toutefois à la résolution de l'écran de l'iPhone - c'est-à-dire à une résolution inférieure.

15
oknox

Juste pour combiner les réponses de Warren et oknox dans un extrait plus court:

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

Personnellement, j'aime bien régler mon failureBlock sur nil.

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

il suffit de fournir le UIReferenceURl que vous avez obtenu pour l'image de la photothèque fournie ci-dessus ... cela fonctionne parfaitement. . Je l’ai affiché dans

  • Cellule UIcollectionView

    ..si tu veux juste l'afficher dans un

  • UIImageView

    veux dire

changement

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

To

imageView.image = copyOfOriginalImage;
8
suku