PhotoKit in Xamarin.iOS

Download Sample Scaricare un esempio di codice

PhotoKit è un framework che consente alle applicazioni di eseguire query sulla libreria di immagini di sistema e creare interfacce utente personalizzate per visualizzarne e modificarne il contenuto. Include una serie di classi che rappresentano asset di immagini e video, nonché raccolte di asset come album e cartelle.

Autorizzazioni

Prima che l'app possa accedere alla raccolta foto, l'utente visualizzerà una finestra di dialogo di autorizzazioni. Devi fornire testo esplicativo nel file Info.plist per spiegare come la tua app usa la raccolta foto, ad esempio:

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

Oggetti modello

PhotoKit rappresenta questi asset in ciò che chiama oggetti modello. Gli oggetti modello che rappresentano le foto e i video stessi sono di tipo PHAsset. Un PHAsset oggetto contiene metadati, ad esempio il tipo di supporto dell'asset e la relativa data di creazione. Analogamente, le PHAssetCollection classi e PHCollectionList contengono i metadati relativi rispettivamente alle raccolte di asset e agli elenchi di raccolte. Le raccolte di asset sono gruppi di asset, ad esempio tutte le foto e i video per un determinato anno. Analogamente, gli elenchi di raccolte sono gruppi di raccolte di asset, ad esempio foto e video raggruppati per anno.

Esecuzione di query sui dati del modello

PhotoKit semplifica l'esecuzione di query sui dati del modello tramite diversi metodi di recupero. Ad esempio, per recuperare tutte le immagini, chiamare PHAsset.Fetch, passando il PHAssetMediaType.Image tipo di supporto.

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

L'istanza PHFetchResult conterrà quindi tutte le istanze che rappresentano le PHAsset immagini. Per ottenere le immagini stesse, usare ( PHImageManager o la versione di memorizzazione nella cache, PHCachingImageManager) per effettuare una richiesta per l'immagine chiamando RequestImageForAsset. Ad esempio, il codice seguente recupera un'immagine per ogni asset in un PHFetchResult oggetto da visualizzare in una cella di visualizzazione raccolta:

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

In questo modo si ottiene una griglia di immagini, come illustrato di seguito:

The running app displaying a grid of images

Salvataggio delle modifiche nella raccolta foto

Ecco come gestire l'esecuzione di query e la lettura dei dati. È anche possibile scrivere di nuovo le modifiche nella libreria. Poiché più applicazioni interessate sono in grado di interagire con la libreria di foto di sistema, è possibile registrare un osservatore per ricevere una notifica delle modifiche tramite un oggetto PhotoLibraryObserver. Quindi, quando vengono apportate modifiche, l'applicazione può aggiornare di conseguenza. Ecco, ad esempio, una semplice implementazione per ricaricare la visualizzazione raccolta precedente:

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

Per scrivere effettivamente le modifiche dall'applicazione, creare una richiesta di modifica. Ognuna delle classi del modello ha una classe di richiesta di modifica associata. Ad esempio, per modificare un PHAssetoggetto , si crea un oggetto PHAssetChangeRequest. I passaggi per eseguire le modifiche che vengono riscritto nella raccolta foto e inviate agli osservatori come quello precedente sono:

  1. Eseguire l'operazione di modifica.
  2. Salvare i dati dell'immagine filtrati in un'istanza PHContentEditingOutput di .
  3. Effettuare una richiesta di modifica per pubblicare le modifiche dall'output di modifica.

Ecco un esempio che scrive di nuovo una modifica in un'immagine che applica un filtro noir core image:

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

Quando l'utente seleziona il pulsante, viene applicato il filtro:

Two examples, showing the photo before and after the filter is applied

Grazie a PHPhotoLibraryChangeObserver, la modifica viene riflessa nella visualizzazione raccolta quando l'utente torna indietro:

Photo collection view showing the modified photo