PhotoKit v Xamarin.iOS
PhotoKit je architektura, která umožňuje aplikacím dotazovat systémovou knihovnu imagí a vytvářet vlastní uživatelská rozhraní k zobrazení a úpravě jeho obsahu. Zahrnuje řadu tříd, které představují obrazové a video assety, a také kolekce prostředků, jako jsou alba a složky.
Oprávnění
Než bude mít aplikace přístup ke knihovně fotek, zobrazí se uživateli dialogové okno s oprávněními. Do souboru Info.plist musíte zadat vysvětlující text, abyste vysvětlili, jak vaše aplikace používá knihovnu fotek, například:
<key>NSPhotoLibraryUsageDescription</key>
<string>Applies filters to photos and updates the original image</string>
Objekty modelu
PhotoKit představuje tyto prostředky v tom, co volá objekty modelu. Objekty modelu, které představují fotografie a videa samy jsou typu PHAsset
. A PHAsset
obsahuje metadata, jako je typ média prostředku a datum jeho vytvoření.
PHAssetCollection
Podobně třídy PHCollectionList
obsahují metadata o kolekcích prostředků a seznamech kolekcí. Kolekce prostředků jsou skupiny prostředků, jako jsou všechny fotky a videa pro daný rok. Seznamy kolekcí jsou také skupiny kolekcí prostředků, jako jsou fotky a videa seskupené podle roku.
Dotazování dat modelu
PhotoKit usnadňuje dotazování dat modelu pomocí různých metod načítání. Například k načtení všech obrázků byste volali PHAsset.Fetch
a předali PHAssetMediaType.Image
typ média.
PHFetchResult fetchResults = PHAsset.FetchAssets (PHAssetMediaType.Image, null);
Instance PHFetchResult
by pak obsahovala všechny PHAsset
instance představující obrázky. K získání samotných imagí použijete PHImageManager
(nebo verzi PHCachingImageManager
ukládání do mezipaměti) k vytvoření požadavku na image voláním RequestImageForAsset
. Například následující kód načte obrázek pro každý prostředek v PHFetchResult
buňce zobrazení kolekce:
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;
}
Výsledkem je mřížka obrázků, jak je znázorněno níže:
Ukládání změn do knihovny fotek
To je postup, jak zpracovávat dotazování a čtení dat. Změny můžete také zapsat zpět do knihovny. Vzhledem k tomu, že více zúčastněných aplikací dokáže pracovat se systémovou knihovnou fotografií, můžete zaregistrovat pozorovatele, který bude upozorněn na změny pomocí PhotoLibraryObserver
. Jakmile se změny objeví, může se vaše aplikace odpovídajícím způsobem aktualizovat. Tady je například jednoduchá implementace pro opětovné načtení výše uvedeného zobrazení kolekce:
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 ();
});
}
}
Pokud chcete změny skutečně zapisovat zpět z aplikace, vytvoříte žádost o změnu. Každá z tříd modelu má přidruženou třídu žádosti o změnu. Chcete-li například změnit , PHAsset
vytvoříte PHAssetChangeRequest
. Postup provedení změn, které se zapisují zpět do knihovny fotografií a odesílají pozorovatelům podobné výše uvedené:
- Proveďte operaci úprav.
- Uložte filtrovaná data obrázku
PHContentEditingOutput
do instance. - Provedením žádosti o změnu publikujte změny z výstupu pro úpravy.
Tady je příklad, který zapíše změnu na obrázek, který použije filtr noir základního obrázku:
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));
});
}
Když uživatel tlačítko vybere, použije se filtr:
A díky PHPhotoLibraryChangeObserver
tomu se změna projeví v zobrazení kolekce, když uživatel přejde zpět: