[Résolu] Resize image sans la dupliquer
busterTheo
Membre
Bonjour,
en travaillant en tant que débutant sur Instruments, et en ayant eu des réponses passionnantes sur ce forum, je cherche à résoudre ce problème :
Suite à ce code que j'ai adapté (si peu !!!) d'après tous les codes du web sur ce sujet que j'ai pu trouver :
func scaledImageWithImage(image: UIImage, size: CGSize) -> UIImage {
let scale: CGFloat = max(size.width/image.size.width, size.height/image.size.height)
let width: CGFloat = image.size.width * scale
let height: CGFloat = image.size.height * scale
let imageRect: CGRect = CGRectMake((size.width-width)/2.0, (size.height-height)/2.0, width, height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
image.drawInRect(imageRect)
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
J'ai eu cette réponse qui m'interpelle :
Dans l'exemple de l'image, c'est normal: tu prends une image, et tu en crées une deuxième, donc il y a un moment où tu as les deux en mémoire.
Et donc, j'ai cherché partout, même sur ce forum, et je ne trouve rien qui me dirait comment faire pour éviter ce problème.
Si quelqu'un a une idée, ce serait super. Merci d'avance.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Tu ne peux pas éviter le problème. Mais tu peux détruire la première image après conversion pour récupérer la mémoire.
Ou plus simplement :
Comme ça, tu évites de faire la destruction à la main (jamais une bonne idée). Swift vas effacer automatiquement l'ancienne version de l'image contenu dans la variable image1.
Où est le problème? A un moment, il faut bien que tu utilises ton image d'origine pour la recopier en version réduite dans ton image d'arrivée fraichement créée...
Ah Draken, je crois avoir compris le truc. Si c'est ça, c'est génial.
C'est d'une logique imparable, et chui pas malin.
D'ailleurs (dans ton code), ce serait plutôt un var que un let. Non ? Mais bon... Pas important.
En gros, si j'ai bien compris, je transformerai ce code :
En ça :
Et pour prouver que je comprend toujours pas complètement les histoire de poneys de Aligator, Xcode (the newbie as Aligator said), me dit de mettre un "!" là :
Merci de me confirmer...
Ta routine de resize est trop compliqué. Tu peux créer le rectangle de destination directement à partir du paramètre size.
C'est mieux, mais pas encore dans l'esprit Swift. On tue encore des poneys, là .
Une autre version, avec une extension de UIImage :
Utilisation :
Ouah, faut que j'aille cherché mon cerveau qui s'est caché dans les limbes du code.
Merci beaucoup.
Hummm, ça c'est beau (avec l'extension, évidemment) :
Plutôt que :
La grande classe. J'adore.
Par contre je comprend pas où tu tues des poneys, dans ton premier code ?
Et, quand tu dis :
je suis super d'accord avec toi, mais le problème est que la photo à resizer est une photo que l'utilisateur de l'appli chargera à partir de l'appareil photo de son ipad, ou de droppBox, ou de son album, et donc je ne peux pas savoir si elle est horizontale ou verticale.
C'est pourquoi, j'ai besoin de cela :
Donc, ... ?
Tu as raison, j'ai tapé le code de mémoire. Je met toujours let pour la création des objets, laissant à Xcode la tâche de me prévenir quand il faut mettre un var.
Oo le beau cadavre de poneys !
Le chargement d'une image peut échouer, donc UIImage(contentsOfFile:) retourne une UImage? (une UIImage optionnelle).
Mais toi, tu obliges le compilateur à utiliser une UImage non optionnelle en forçant son type. Xcode a donc besoin de convertir l'image optionnelle en non optionnelle en ajoutant un !. Pas bien ..
Il faut écrire :
pour ne pas forcer une conversion inutile et dangereuse. Si le chargement de l'image échoue pour une raison ou une autre, UIImage(contentsOfFile) var retourner nil. Ton application vas planter en tentant de convertir le nil en UIImage.
Plus simple encore :
UIImage retournant une UIImage?, Xcode sait que zeImage doit être de type UIImage? sans ajouter de déclarations inutiles.
Mort de rire, j'en ai mal aux cheveux.
Mais bon, je commence à peine à comprendre.
Ok, pas de forçage de type.
Mais xcode m'oblige à présent à mettre encore un "!", et ce coup-ci au zeImage, dans l'appel du scaledWithImage :
Oups, un poney peut-il en cacher un autre ?
En retournant un UIImage et non un UIImage?. L'opération de resize peut échouer pour une raison quelconque.
Sorry, je n'avais pas compris le truc. Je t'ai écrit une fonction générique "basique", sans penser à ce problème d'orientation, que je n'ai jamais rencontré.
T'inquiètes... À moi de l'adapter. Je devrais m'en sortir. Merci.
C'est parce que scaledImageWithImage() demande une UIImage non optionnelle en entrée. Tu pourrais en faire une nouvelle version demandant une UIImage? et retournant une UIImage?, pour être dans l'esprit Swift. J'avais commencé à le faire, puis j'ai préféré écrire une extension pour être encore plus Swifty.
https://github.com/AliSoftware/UIImage-Resize
Parce qu'il y a un truc que tu ne gères pas, ce sont les rotations "virtuelles" EXIF. En gros, les images sont orientées telles que prises par le capteur photo. Il y a un attribut dans le fichier qui indique l'orientation réelle.
ça pose un vrai problème quand tu prends des images dans l'album photo ou avec la caméra. Auquel cas lorsque la photo a été prise en orientation "portrait", elle se retrouve tournée de ±90° ou 180°. Il faut le gérer lors du redimensionnement.
Très instructif ce fil !
Et pour les poneys je viens de comprendre à la lecture du blog d'AliGator...
Faut suivre !
Ouaaah, merci. Je regarde tout ça, et reviens bientôt au bar.
Ah c'est de l'objectiveC, va fallloir que je fasse marcher mes méninges à 400%...
ok merci pour l'info