PhotoKit w środowisku Xamarin.iOS
PhotoKit to struktura, która umożliwia aplikacjom wykonywanie zapytań dotyczących biblioteki obrazów systemowych i tworzenie niestandardowych interfejsów użytkownika w celu wyświetlania i modyfikowania jego zawartości. Zawiera ona szereg klas reprezentujących zasoby obrazów i wideo, a także kolekcje zasobów, takich jak albumy i foldery.
Uprawnienia
Zanim aplikacja będzie mogła uzyskać dostęp do biblioteki zdjęć, zostanie wyświetlone okno dialogowe uprawnień. Musisz podać tekst objaśniający w pliku Info.plist , aby wyjaśnić, jak aplikacja korzysta z biblioteki zdjęć, na przykład:
<key>NSPhotoLibraryUsageDescription</key>
<string>Applies filters to photos and updates the original image</string>
Obiekty modelu
Zestaw PhotoKit reprezentuje te zasoby w obiektach modelu. Obiekty modelu reprezentujące same zdjęcia i filmy wideo są typu PHAsset
. Element PHAsset
zawiera metadane, takie jak typ nośnika zasobu i jego data utworzenia.
PHAssetCollection
Podobnie klasy i PHCollectionList
zawierają metadane dotyczące kolekcji zasobów i list kolekcji odpowiednio. Kolekcje zasobów to grupy zasobów, takie jak wszystkie zdjęcia i filmy wideo w danym roku. Podobnie listy kolekcji to grupy kolekcji zasobów, takie jak zdjęcia i filmy wideo pogrupowane według roku.
Wykonywanie zapytań dotyczących danych modelu
Zestaw PhotoKit ułatwia wykonywanie zapytań dotyczących danych modelu za pomocą różnych metod pobierania. Aby na przykład pobrać wszystkie obrazy, należy wywołać PHAsset.Fetch
metodę , przekazując typ nośnika PHAssetMediaType.Image
.
PHFetchResult fetchResults = PHAsset.FetchAssets (PHAssetMediaType.Image, null);
Następnie PHFetchResult
wystąpienie będzie zawierać wszystkie PHAsset
wystąpienia reprezentujące obrazy. Aby uzyskać same obrazy, należy użyć PHImageManager
(lub wersji buforowania), PHCachingImageManager
aby wysłać żądanie dotyczące obrazu, wywołując metodę RequestImageForAsset
. Na przykład poniższy kod pobiera obraz dla każdego zasobu w obiekcie PHFetchResult
, który ma być wyświetlany w komórce widoku kolekcji:
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;
}
Spowoduje to wyświetlenie siatki obrazów, jak pokazano poniżej:
Zapisywanie zmian w bibliotece zdjęć
W ten sposób można obsługiwać wykonywanie zapytań i odczytywanie danych. Możesz również zapisać zmiany z powrotem do biblioteki. Ponieważ wiele zainteresowanych aplikacji może wchodzić w interakcje z systemową biblioteką zdjęć, można zarejestrować obserwatora, aby otrzymywać powiadomienia o zmianach przy użyciu elementu PhotoLibraryObserver
. Następnie po wprowadzeniu zmian aplikacja może odpowiednio zaktualizować. Na przykład poniżej przedstawiono prostą implementację, aby ponownie załadować widok kolekcji powyżej:
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 ();
});
}
}
Aby faktycznie zapisać zmiany z aplikacji, należy utworzyć żądanie zmiany. Każda z klas modelu ma skojarzona klasa żądania zmiany. Aby na przykład zmienić element PHAsset
, należy utworzyć element PHAssetChangeRequest
. Kroki umożliwiające wykonanie zmian, które są zapisywane z powrotem w bibliotece zdjęć i wysyłane do obserwatorów, takich jak powyższe, to:
- Wykonaj operację edycji.
- Zapisz przefiltrowane dane obrazu w wystąpieniu
PHContentEditingOutput
. - Wprowadź żądanie zmiany, aby opublikować zmiany z danych wyjściowych edycji.
Oto przykład, który zapisuje zmianę obrazu, który stosuje filtr Noir obrazu podstawowego:
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));
});
}
Gdy użytkownik wybierze przycisk, zostanie zastosowany filtr:
PHPhotoLibraryChangeObserver
Dzięki funkcji zmiana zostanie odzwierciedlona w widoku kolekcji, gdy użytkownik przejdzie z powrotem: