2015-09-01 17 views
50

Wie kann ich die größte auf einem iOS-Gerät verfügbare Bildgröße PHAsset ermitteln? Mit "verfügbar" meine ich derzeit auf dem Gerät, ohne dass ein Netzwerkdownload von iCloud Photo Library erforderlich ist ?Ermitteln der größten auf iOS-Geräten verfügbaren Bildgröße des PHAsset

Ich habe eine App entwickelt, in der eine Sammlung von Miniaturansichten in einer UICollectionView (ähnlich wie die Fotos App) angezeigt wird und dann kann ein Benutzer ein Bild auswählen, um es in voller Größe anzuzeigen. Das vollständige Bild wird bei Bedarf von iCloud heruntergeladen. Ich möchte jedoch dem Benutzer die größtmögliche Version des Bildes zeigen, bis die volle Größe verfügbar ist.

Die Art und Weise die Fotos Rahmen funktioniert, ist ziemlich seltsam:

In der Sammlung Ansicht, ich bin ein PHCachingImageManager zu cache (und später request) Bilder mit einem targetSize von 186x186 Pixel (das Doppelte der UICollectionViewCell-Dimensionen wegen Netzhaut-Skalierung).

Das funktioniert sehr gut, mit sehr schnellen Scrolling und keine Verzögerung beim Füllen der Zellen mit Bildern. Wenn Sie die Größe der zurückgegebenen Bilder überprüfen, sind sie ungefähr 342 x 256 Pixel groß. Das ist auf meinem iPhone 6 mit iCloud Photo Library aktiviert und "Speicher optimieren" aktiviert, so dass nur kleine Vorschaubilder auf dem Gerät für die meisten Bilder gespeichert sind.

jedoch der ungeradee Teil ist, dass, wenn ich dann die volle Größe (oder viel größer) Version eines Bildes beantragen, entweder mit PHCachingImageManager oder PHImageManager.defaultManager() die PHImageRequestOptionsDeliveryMode.Opportunistic Option, das erste (niedrige Qualität) Bild, das zurückgegeben wird, ist ein winzige 60x45 Pixel Briefmarke, die schrecklich auf dem ganzen Bildschirm aussieht, bis schließlich das Bild in voller Größe heruntergeladen wird, um es zu ersetzen.

Klar gibt es sind größere Thumbnails (342x256) auf dem Gerät bereits, wie sie gerade in der Sammlung angezeigt wurden! Also warum zur Hölle gibt es sie nicht als das erste Bild mit niedriger Qualität zurück, bis die volle Größe heruntergeladen wurde? Um sicherzustellen, dass die 342x256 Bilder wirklich auf dem Gerät waren, habe ich den Code im Flugzeugmodus ausgeführt, so dass kein Netzwerkzugriff stattfand.

Was ich fand, war, dass, wenn ich irgendeine Größe bis zu 256x256 anforderte, ich die 342x256 Bilder zurückbekommen würde. Sobald ich größer (sogar 1 Pixel) ging, würde ich zuerst 60x45 Bilder zurückgeben und dann versuchen, das volle Bild herunterzuladen.

Ich habe meinen Code geändert, um zuerst eine 256x256-Anfrage zu machen, gefolgt von einer Anfrage in voller Größe mit PHImageRequestOptionsDeliveryMode.HighQualityFormat (die kein winziges Zwischenbild zurückgibt), und das funktioniert wunderbar. Dies ist auch die Aufgabe der iOS-Fotos-App, da sie Thumbnails von relativ hoher Qualität anzeigt, während das gesamte Bild heruntergeladen wird.

Also, mit diesem Hintergrund, woher weiß ich, was das größte Gerät Bildgröße für eine PHAsset ist? Ist 256x256 eine magische Zahl oder hängt es davon ab, wie iCloud Photo Library den Speicherplatz optimiert (basierend auf der Größe der Bibliothek und dem verfügbaren Gerätespeicher)?

Sicher scheint wie ein Fehler, dass Photos Framework nicht das größte derzeit verfügbare Bild zurückgibt (wenn nach einer Größe größer als es derzeit gefragt wird), und dass die größte Größe, die es hat, müssen Sie darum bitten Größe oder kleiner, denn wenn Sie nach etwas größerem fragen, erhalten Sie eine 60x45 Miniatur! Bizarr.

UPDATE: Bugreport Apple eingereicht: https://openradar.appspot.com/25181601
Beispielprojekt, das den Fehler zeigt: https://github.com/mluisbrown/PhotoKitBug

+0

Während Sie Thumbnails abrufen, machen Sie eine synchrone oder asynchrone Anfrage mit PHImageManager.defaultManager()? –

+0

@ArunAmmannaya Ich benutze einen 'PHCachingImageManager', um die Thumbnails zu erhalten, und die Anfrage ist asynchron. – mluisbrown

+0

Dann werden Sie mehrere Callback für einzelnes Bild mit verschiedenen Größen für das angeforderte Bild erhalten. Wie oft wird der Rückruf angerufen? –

Antwort

1

Mit dem Beispielprojekt geschrieben in der Frage ich in der Lage war, das Problem zu reproduzieren im Simulator, aber wenn ich habe die folgende Änderung würde ich erhalten nur das größte Bild:

let targetSize = PHImageManagerMaximumSize 
+0

Verwenden von 'PHImageManagerMaximumSize' für die Zielgröße bedeutet, dass Sie mir das Bild mit der vollen Auflösung oder nichts, wenn es nicht verfügbar ist. Auf dem Simulator ist das Bild mit voller Auflösung immer verfügbar. Auf einem Gerät sind die vollständigen Res Bilder von iCloud Photo Library jedoch normalerweise nicht verfügbar. Die Verwendung von 'PHImageManagerMaximumSize' im Beispielprojekt gibt kein Bild zurück, da die Option' networkAccessAllowed = false' verwendet wird. Also das wird nicht helfen, ich habe Angst :-( – mluisbrown

+0

@mluisbrown Circling zurück zu diesem. Was ist Protokoll hier? Sollte ich diese Antwort löschen, oder behalten Sie es so, dass andere nicht die gleiche Antwort posten (offensichtlich, dass nicht Wirklich Arbeit)? – markwatsonatx

+0

Mark, ich denke, du solltest die Antwort verlassen. Es war ein gültiger Vorschlag. Als ich es sah lief ich zurück zu meinem Mac dachte "Könnte es wirklich so offensichtlich sein?" Wertvolle Abstimmung in der Tat :) – mluisbrown

-2
[imageManager requestImageForAsset:asset 
       targetSize: PHImageManagerMaximumSize 
       contentMode:PHImageContentModeAspectFill 
       options:nil 
resultHandler:^(UIImage *result, NSDictionary *info) 
{ 
    result; 
}]; 
+1

Wenn Sie sich die Mühe gemacht hätten, Mark Watsons Antwort zu lesen, würden Sie wissen, warum das nicht funktioniert (lesen Sie meinen Kommentar zu dieser Antwort). – mluisbrown

0

Eigentlich ich nicht kn Der Grund, warum Apple das degradierte 45 * 60 Bild mit PHImageResultIsDegradedKey = 1 zurückgeben würde. Für mich, ich ersuche nur das 256 * 256 Bild mit deliveryMode PHImageRequestOptionsDeliveryModeHighQualityFormat zuerst, dann verwende ich die anderen PHImageRequestOptions wie Bild in voller Größe anzufordern unter:

PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; 
options.networkAccessAllowed = YES; 
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; 
options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info){ 
// code to update the iCloud download progress 
}); 

[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) { 
// code to update UIImageView or something else. 
}); 

Und ich denke, kann Instagram diese ähnliche Lösung verwenden zu Behandle das Bild von iCloud.