Partager via


PhotoKit dans Xamarin.iOS

PhotoKit est une infrastructure qui permet aux applications d’interroger la bibliothèque d’images système et de créer des interfaces utilisateur personnalisées pour afficher et modifier son contenu. Il comprend un certain nombre de classes qui représentent des ressources image et vidéo, ainsi que des collections de ressources telles que des albums et des dossiers.

Autorisations

Avant que votre application puisse accéder à la bibliothèque de photos, l’utilisateur reçoit une boîte de dialogue d’autorisations. Vous devez fournir du texte explicatif dans le fichier Info.plist pour expliquer comment votre application utilise la bibliothèque de photos, par exemple :

<key>NSPhotoLibraryUsageDescription</key>
<string>Applies filters to photos and updates the original image</string>

Objets de modèle

PhotoKit représente ces ressources dans ce qu’elle appelle des objets de modèle. Les objets de modèle qui représentent les photos et vidéos elles-mêmes sont de type PHAsset. Contient PHAsset des métadonnées telles que le type de média de la ressource et sa date de création. De même, les PHAssetCollection classes et PHCollectionList les classes contiennent des métadonnées sur les collections de ressources et les listes de collections respectivement. Les collections d’actifs sont des groupes de ressources, tels que toutes les photos et vidéos pour une année donnée. De même, les listes de collections sont des groupes de collections d’actifs, telles que des photos et des vidéos regroupées par année.

Interrogation des données de modèle

PhotoKit facilite l’interrogation des données de modèle par le biais de diverses méthodes d’extraction. Par exemple, pour récupérer toutes les images, vous appelez PHAsset.Fetch, en passant le type de PHAssetMediaType.Image média.

PHFetchResult fetchResults = PHAsset.FetchAssets (PHAssetMediaType.Image, null);

L’instance PHFetchResult contient ensuite toutes les PHAsset instances représentant des images. Pour obtenir les images elles-mêmes, vous utilisez la PHImageManager (ou la version de mise en cache, PHCachingImageManager) pour effectuer une demande pour l’image en appelant RequestImageForAsset. Par exemple, le code suivant récupère une image pour chaque élément multimédia dans une PHFetchResult cellule d’affichage de collection :

public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
{
    var imageCell = (ImageCell)collectionView.DequeueReusableCell (cellId, indexPath);
    imageMgr.RequestImageForAsset (
        (PHAsset)fetchResults [(uint)indexPath.Item],
        thumbnailSize,
        PHImageContentMode.AspectFill, new PHImageRequestOptions (),
        (img, info) => {
            imageCell.ImageView.Image = img;
        }
    );
    return imageCell;
}

Cela entraîne une grille d’images, comme indiqué ci-dessous :

Application en cours d’exécution affichant une grille d’images

Enregistrement des modifications dans la bibliothèque de photos

C’est comment gérer l’interrogation et la lecture des données. Vous pouvez également réécrire les modifications dans la bibliothèque. Étant donné que plusieurs applications intéressées sont en mesure d’interagir avec la bibliothèque de photos système, vous pouvez inscrire un observateur pour être informé des modifications à l’aide d’un PhotoLibraryObserver. Ensuite, lorsque les modifications sont apportées, votre application peut être mise à jour en conséquence. Par exemple, voici une implémentation simple pour recharger la vue collection ci-dessus :

class PhotoLibraryObserver : PHPhotoLibraryChangeObserver
{
    readonly PhotosViewController controller;
    public PhotoLibraryObserver (PhotosViewController controller)

    {
        this.controller = controller;
    }

    public override void PhotoLibraryDidChange (PHChange changeInstance)
    {
        DispatchQueue.MainQueue.DispatchAsync (() => {
            var changes = changeInstance.GetFetchResultChangeDetails (controller.fetchResults);
            controller.fetchResults = changes.FetchResultAfterChanges;
            controller.CollectionView.ReloadData ();
        });
    }
}

Pour réécrire réellement les modifications de votre application, vous créez une demande de modification. Chacune des classes de modèle a une classe de demande de modification associée. Par exemple, pour modifier un PHAsset, vous créez un PHAssetChangeRequest. Les étapes d’exécution des modifications écrites dans la bibliothèque de photos et envoyées aux observateurs comme celui ci-dessus sont les suivantes :

  1. Effectuez l’opération d’édition.
  2. Enregistrez les données d’image filtrées dans une PHContentEditingOutput instance.
  3. Effectuez une demande de modification pour publier les modifications à partir de la sortie d’édition.

Voici un exemple qui écrit une modification dans une image qui applique un filtre Core Image noir :

void ApplyNoirFilter (object sender, EventArgs e)
{
    Asset.RequestContentEditingInput (new PHContentEditingInputRequestOptions (), (input, options) => {

        // perform the editing operation, which applies a noir filter in this case
        var image = CIImage.FromUrl (input.FullSizeImageUrl);
        image = image.CreateWithOrientation((CIImageOrientation)input.FullSizeImageOrientation);
        var noir = new CIPhotoEffectNoir {
            Image = image
        };
        var ciContext = CIContext.FromOptions (null);
        var output = noir.OutputImage;
        var uiImage = UIImage.FromImage (ciContext.CreateCGImage (output, output.Extent));
        imageView.Image = uiImage;
        //
        // save the filtered image data to a PHContentEditingOutput instance
        var editingOutput = new PHContentEditingOutput(input);
        var adjustmentData = new PHAdjustmentData();
        var data = uiImage.AsJPEG();
        NSError error;
        data.Save(editingOutput.RenderedContentUrl, false, out error);
        editingOutput.AdjustmentData = adjustmentData;
        //
        // make a change request to publish the changes form the editing output
        PHPhotoLibrary.GetSharedPhotoLibrary.PerformChanges (() => {
            PHAssetChangeRequest request = PHAssetChangeRequest.ChangeRequest(Asset);
            request.ContentEditingOutput = editingOutput;
        },
        (ok, err) => Console.WriteLine ("photo updated successfully: {0}", ok));
    });
}

Lorsque l’utilisateur sélectionne le bouton, le filtre est appliqué :

Deux exemples, montrant la photo avant et après l’application du filtre

Et grâce au PHPhotoLibraryChangeObserverchangement, la modification est reflétée dans l’affichage collection lorsque l’utilisateur revient :

Vue de collection de photos montrant la photo modifiée