Image Upload dauert ewig lange

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • @MCDan

    actual size of image in KB: %f 2238.447
    actual size of image in KB: %f 1370.75
    actual size of image in KB: %f 914.208
    actual size of body in KB: %f 4523.929

    Ob das ganze jetzt in Base64 umgewandelt wird kann weiß ich leider nicht :/ Aber anhand der Bildergrößen sieht man das die schon kleiner sind als die 24 Mb die ich am Anfang durch das encoden hatte...

    Was ist denn die Standardgröße für Bilder Uploads ? Würde es Sinn machen ab einer bestimmten Größe das Bild zu resizen ?
  • MCDan schrieb:

    Hm, werden Binary Daten dabei nicht automatisch auch in Base64 umgewandelt?

    Lass Dir doch mal die Größe der einzelnen Media.data und des kompletten body ausgeben.
    Die werden nicht gewandelt.
    Einfach mal CFNETWORK_DIAGNOSTICS anschalten und dann sieht man alles. Die Größe der übertragenen Daten die Dauer usw.
    Man macht einfach solange irgendwelche Dinge, bis man tot ist.
    Und dann bekommen die anderen Kuchen.
  • ThisIsBeat schrieb:

    @MCDan

    actual size of image in KB: %f 2238.447
    actual size of image in KB: %f 1370.75
    actual size of image in KB: %f 914.208
    actual size of body in KB: %f 4523.929

    Ob das ganze jetzt in Base64 umgewandelt wird kann weiß ich leider nicht :/ Aber anhand der Bildergrößen sieht man das die schon kleiner sind als die 24 Mb die ich am Anfang durch das encoden hatte...

    Was ist denn die Standardgröße für Bilder Uploads ? Würde es Sinn machen ab einer bestimmten Größe das Bild zu resizen ?
    Bei einer automatischen Umwandlung in Base64 müsste der Body eine Größe von ca. 6062 haben. Somit scheint da nichts umgewandelt zu werden.

    Eine Standardgröße für Bilder Uploads gibt es nicht. Es hängt halt davon ab, was Du mit den Bildern machen möchtest.
  • Nun ja ich hab jetzt die maximale Größe der Bilder auf 1080 x 1920 angepasst was in meinen Augen mehr als ausreichend ist. Dadurch konnte ich die Größe der Bilder jetzt noch weiter runterschrauben und dabei die gleiche Qualität beibehalten :D
    Aber es freut mich das ich das ganze jetzt mit eurer Hilfe in den Griff bekommen habe, vielen Dank dafür !

    Ich habe da aber noch ein weiteres Qualitätsproblem mit Bildern und wollte hier mal nachfragen ob jemand von euch vielleicht noch einen guten Tipp dazu parat hätte bevor ich dazu ein neues Thema eröffne.

    Es geht darum das ich mir meinen eigenen Multiple Image Picker gebaut habe. Das heißt bevor es zum Upload der Bilder kommt, lade ich alle Bilder die sich auf dem Gerät eines Nutzers befinden in eine CollectionView.
    In dieser CollectionView kann der User halt aussuchen welche seiner Bilder er hochladen möchte. So nun lade ich diese Bilder natürlich nicht in der allerhöchsten Auflösung in die kleinen CollectionViewCells sondern passe das ganze an, damit die ganzen Bilder schneller in die Zellen geladen werden..
    Das ganze mache ich so:

    Quellcode

    1. let imgManager = PHImageManager.default()
    2. let requestOptions = PHImageRequestOptions()
    3. requestOptions.isSynchronous = true
    4. requestOptions.deliveryMode = .highQualityFormat
    5. //Nach Datum ordnen
    6. let fetchOptions = PHFetchOptions()
    7. fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    8. fetchResult = PHAsset.fetchAssets(with: fetchOptions)
    9. print(fetchResult)
    10. if fetchResult.count > 0 {
    11. for i in 0..<fetchResult.count {
    12. imgManager.requestImage(for: fetchResult.object(at: i) , targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions, resultHandler: {
    13. image, error in
    14. self.imageArray.append(image!)
    15. })
    16. }
    17. } else {
    18. print("You got no photos")
    19. collectionView.reloadData()
    20. }
    Alles anzeigen



    Problem daran ist folgendes: Ich packe die Bilder die der User auswählt in ein Array. Leider haben die Bilder dann nicht die Original Qualität/Größe
    sondern die Qualität/Größe die ich ihnen zuvor gegeben habe.

    Aktuell habe ich eine ziemlich hässliche Lösung um doch noch eine bessere Qualität zu bekommen und zwar lasse ich an einer anderen Stelle folgenden Code noch parallel zusätzlich mitlaufen:

    Quellcode

    1. imgManager.requestImage(for: fetchResult.object(at: indexPath.row) , targetSize: CGSize(width: 360, height: 640), contentMode: .aspectFill, options: requestOptionsImage, resultHandler: {
    2. image, error in
    3. otherArray.append(image!)
    4. })

    Mir ist aber klar dass das nicht die Lösung sein kann...

    Jetzt meine Frage:
    Wie komme ich im Nachhinein noch an das Original Format bzw. die Qualität des Bildes ran ?
  • Anstelle eines Array mit UIImage Objekten ist es vielleicht hilfreich eine Klasse mit dem PHAsset und dem UIImage zu verwenden. Dann hast Du bei Auswahl eines Image auch gleich Zugriff auf das passende PHAsset und kannst das Image damit erneut über den PHImageManager laden. ;)

    BTW: Je nachdem wie viele Bilder der Anwender in seiner Photo Library hat, solltest Du evtl. den PHCachingImageManager und nicht den PHImageManager verwenden.
  • MCDan schrieb:

    Anstelle eines Array mit UIImage Objekten ist es vielleicht hilfreich eine Klasse mit dem PHAsset und dem UIImage zu verwenden. Dann hast Du bei Auswahl eines Image auch gleich Zugriff auf das passende PHAsset und kannst das Image damit erneut über den PHImageManager laden. ;)

    BTW: Je nachdem wie viele Bilder der Anwender in seiner Photo Library hat, solltest Du evtl. den PHCachingImageManager und nicht den PHImageManager verwenden.
    Sprichst du von einer Klasse oder einem Dictionary ? Wäre die Zuordnung von UImage und PHAsset in einem Dictionary nicht einfacher ? Ich habe mal beide Möglichkeiten gecodet, so stellst du dir das doch mit der Klasse vor oder nicht ?

    Bin gerade hin und her gerissen dazwischen ob Klasse oder Dictionary hier jetzt Sinn macht...

    Quellcode

    1. // Beispiel mit Dictionary
    2. let dictionary = [[UIImage: PHAsset]]
    3. // Beispiel mit Klasse
    4. class FetchResult {
    5. let image: [UIImage]
    6. let asset: [PHFetchResult<PHAsset>!]
    7. init(image: [UIImage], asset: [PHFetchResult<PHAsset>!]) {
    8. self.image = image
    9. self.asset = asset
    10. }
    11. }
    Alles anzeigen

    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von ThisIsBeat ()

  • MCDan schrieb:

    BTW: Je nachdem wie viele Bilder der Anwender in seiner Photo Library hat, solltest Du evtl. den PHCachingImageManager und nicht den PHImageManager verwenden.
    Ich habe mich jetzt auch mal damit beschäftigt und eine Funktion geschrieben:

    Quellcode

    1. func startCachingImages() {
    2. let imgManager = PHCachingImageManager()
    3. let requestOptions = PHImageRequestOptions()
    4. requestOptions.isSynchronous = true
    5. requestOptions.deliveryMode = .highQualityFormat
    6. //Nach Datum ordnen
    7. let fetchOptions = PHFetchOptions()
    8. fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    9. fetchResult = PHAsset.fetchAssets(with: fetchOptions)
    10. let indexSet = IndexSet(0..<fetchResult.count)
    11. imgManager.startCachingImages(for: fetchResult.objects(at: indexSet), targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions)
    12. }
    Alles anzeigen
    Ich frage mich gerade nur an welcher Stelle ich diese aufrufen sollte. Aktuell habe ich sie in meiner viewDidAppear() drin da das für mich jetzt so am meisten Sinn gemacht hat da die andere Funktion mit dem requestImage in der viewDidLoad aufgerufen wird.

    Macht das so Sinn ? Und gibt es eventuell eine Möglichkeit zu überprüfen ob sich die Bilder nach dem Anruf in der viewDidAppear auch wirklich im Cache befinden ?

    Ich frage mich halt wie ich sicher sein kann das requestImage bei Verwendung dann auch sicher ein Bild aus dem Cache nimmt...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ThisIsBeat ()

  • Wenn PHCachingImageManager direkt alle Bilder in den Cache laden würde, dann wäre die Klasse ja recht sinnlos.

    Ich tippe jetzt einfach mal, dass immer ein paar neue Bilder geladen werden, je nachdem welches Bild zuletzt angefordert wurde.

    Weiterhin ist requestImage(for:targetSize:contentMode:options:resultHandler:) ja eh schon asynchron ausgelegt, so dass das Bild beim Aufruf evtl. nicht direkt zur Verfügung steht. Sprich der resultHandler nicht direkt aufgerufen wird, wenn das Bild noch nicht im Cache war. Daher musst Du das Füllen der CollectionViewCells also eh schon asynchron aufbauen.