PhotoKit in Xamarin.iOS
PhotoKit ist ein Framework, mit dem Anwendungen die Systembildbibliothek abfragen und benutzerdefinierte Benutzeroberflächen erstellen können, um deren Inhalt anzuzeigen und zu ändern. Es umfasst eine Reihe von Klassen, die Bild- und Videoressourcen darstellen, sowie Sammlungen von Ressourcen wie Alben und Ordnern.
Bevor Ihre App auf die Fotobibliothek zugreifen kann, wird dem Benutzer ein Berechtigungsdialogfeld angezeigt. Sie müssen erläuternden Text in der Datei Info.plist angeben, um zu erläutern, wie Ihre App die Fotobibliothek verwendet, z. B.:
<key>NSPhotoLibraryUsageDescription</key>
<string>Applies filters to photos and updates the original image</string>
PhotoKit stellt diese Ressourcen in der Aufrufung von Modellobjekten dar. Die Modellobjekte, die die Fotos und Videos selbst darstellen, sind vom Typ PHAsset
. A PHAsset
enthält Metadaten wie den Medientyp der Ressource und das Erstellungsdatum.
Entsprechend enthalten die PHAssetCollection
Klassen PHCollectionList
Metadaten zu Objektsammlungen bzw. Sammlungslisten. Objektsammlungen sind Gruppen von Objekten, z. B. alle Fotos und Videos für ein bestimmtes Jahr. Ebenso sind Sammlungslisten Gruppen von Objektsammlungen, z. B. Fotos und Videos, die nach Jahr gruppiert sind.
PhotoKit erleichtert das Abfragen von Modelldaten über eine Vielzahl von Abrufmethoden. Wenn Sie beispielsweise alle Bilder abrufen möchten, würden Sie den PHAsset.Fetch
Medientyp übergeben PHAssetMediaType.Image
.
PHFetchResult fetchResults = PHAsset.FetchAssets (PHAssetMediaType.Image, null);
Die PHFetchResult
Instanz würde dann alle Instanzen enthalten, die PHAsset
Bilder darstellen. Um die Bilder selbst abzurufen, verwenden Sie die PHImageManager
(oder die Zwischenspeicherungsversion PHCachingImageManager
), um eine Anforderung für das Bild durch Aufrufen RequestImageForAsset
zu stellen. Der folgende Code ruft z. B. ein Bild für jedes Objekt in einer PHFetchResult
Sammlungsansichtszelle ab:
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;
}
Dies führt zu einem Raster mit Bildern, wie unten dargestellt:
So behandeln Sie Abfragen und Lesen von Daten. Sie können auch Änderungen zurück in die Bibliothek schreiben. Da mehrere interessierte Anwendungen in der Lage sind, mit der Systemfotobibliothek zu interagieren, können Sie einen Beobachter registrieren, um über Änderungen über ein PhotoLibraryObserver
. Wenn dann Änderungen vorgenommen werden, kann Ihre Anwendung entsprechend aktualisiert werden. Hier ist beispielsweise eine einfache Implementierung, um die Sammlungsansicht oben neu zu laden:
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 ();
});
}
}
Wenn Sie Änderungen tatsächlich aus Ihrer Anwendung zurückschreiben möchten, erstellen Sie eine Änderungsanforderung. Jede der Modellklassen weist eine zugeordnete Änderungsanforderungsklasse auf. Zum Ändern eines Beispiels PHAsset
erstellen Sie eine PHAssetChangeRequest
. Die Schritte zum Ausführen von Änderungen, die in die Fotobibliothek zurückgeschrieben und an Beobachter wie die oben beschriebene gesendet werden:
- Führen Sie den Bearbeitungsvorgang aus.
- Speichern Sie die gefilterten Bilddaten in einer
PHContentEditingOutput
Instanz. - Nehmen Sie eine Änderungsanforderung vor, um die Änderungen aus der Bearbeitungsausgabe zu veröffentlichen.
Hier ist ein Beispiel, das eine Änderung auf ein Bild zurück schreibt, das einen Core Image Noir-Filter anwendet:
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));
});
}
Wenn der Benutzer die Schaltfläche auswählt, wird der Filter angewendet:
Und dank der PHPhotoLibraryChangeObserver
Änderung wird die Änderung in der Sammlungsansicht wiedergegeben, wenn der Benutzer zurück navigiert: