PhotoKit dans Xamarin.iOS

Télécharger l’exemple Télécharger un exemple de code

PhotoKit est un framework 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, une boîte de dialogue d’autorisations s’affiche à l’utilisateur. Vous devez fournir un texte explicatif dans le fichier Info.plist pour expliquer comment votre application utilise la photothèque, 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’il 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. Un PHAsset contient 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 contiennent des métadonnées sur les collections de ressources et les listes de collections respectivement. Les collections de biens sont des groupes de ressources, comme toutes les photos et vidéos d’une année donnée. De même, les listes de collections sont des groupes de collections de biens, tels 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 via 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);

Le PHFetchResult instance contiendrait alors toutes les instances représentant des PHAsset images. Pour obtenir les images elles-mêmes, vous utilisez ( 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 ressource d’un PHFetchResult à afficher dans une 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;
}

Il en résulte une grille d’images comme indiqué ci-dessous :

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

Enregistrement des modifications apportées à la photothèque

Voici comment gérer l’interrogation et la lecture des données. Vous pouvez également réécrire des modifications dans la bibliothèque. Étant donné que plusieurs applications intéressées sont en mesure d’interagir avec la photothèque système, vous pouvez inscrire un observateur pour être informé des modifications à l’aide d’un PhotoLibraryObserver. Ensuite, lorsque des modifications arrivent, votre application peut se mettre à jour en conséquence. Par exemple, voici une implémentation simple pour recharger la vue de 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 écrire réellement des modifications à partir 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 permettant d’effectuer des modifications qui sont réécrites dans la photothèque et envoyées à des observateurs comme celui ci-dessus sont les suivantes :

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

Voici un exemple qui réécrit une modification d’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 à , PHPhotoLibraryChangeObserverla modification est répercutée dans la vue de collection lorsque l’utilisateur navigue en arrière :

Affichage de la collection de photos montrant la photo modifiée