Chargement d'une NSImage

GGGG Membre
18:35 modifié dans API AppKit #1
Bonjour à  tous,<br />je suis en train de faire une application qui charge des images dans une NSMatrix.<br />Voilà  la problématique :<br /><br />lorsque je charge de cette manière :<br />[code]<br /><br />image = [[NSimage alloc] initwithcontentoffile:filename];<br /><br />


et que je modifie la taille en mémoire de l'image, je remarque plusieurs choses :
- la mémoire est extremement sollicité
- et je passe beaucoup de temps (80% du temps total du chargement) à  réduire la taille en mémoire de ces images.

Si je passe par :
<br /><br />image = [[NSImage alloc]initByReferencingFile:filename];<br /><br />


Les performances se dégradent de manière importante.

Existe t'il un moyen pour que la NSTiffrepresentation soit au chargement de la taille que l'on veut ?
En gros éviter de tout charger en mémoire et réduire ensuite cette taille.

Réponses

  • AliGatorAliGator Membre, Modérateur
    18:35 modifié #2
    Comment redimentionnes-tu ton image ?
    Le sujet a été plusieurs fois abordé déjà  sur OC :
    - si tu passes par un setSize, sache que ça ne redimentionne pas réellement l'image, il dit juste à  quelle taille l'image est rendue mais ça ne modifie pas la taille qu'elle prend en mémoire
    - Sinon y'a des codes qui trainent pour réellement redimentionner une image : via des NSAffineTransforms, ou via des codes comme a donné Bru ici

    Selon la méthode que tu utilises pour faire ton redimentionnement, ça prendra pas les mêmes ressources (et la qualité finale ne sera pas forcément la même non plus).

    Par contre je doute que tu puisses charger l'image directement à  la taille que tu veux : lorsqu'on a une image sur le disque, la représentation binaire (le contenu du fichier quoi) qu'elle contient décrit chacun des pixels composant l'image. Donc quand tu ouvres l'image tu charges forcément les données représentant les pixels, à  la taille où l'image a été enregistrée.
    Donc tu es obligé de charger l'image, de la redimentionner, puis de relâcher la version grande taille pour libérer de la place et ne garder que la version redimentionnée...
  • schlumschlum Membre
    18:35 modifié #3
    On doit pouvoir, mais dans ce cas il ne faut pas utiliser les méthodes Cocoa...
    Il faut lire un bout du fichier, travailler dessus, lire un autre bout etc.
  • psychoh13psychoh13 Mothership Developer Membre
    18:35 modifié #4
    Je pense qu'il est plus simple de dessiner la NSImage source dans dans une NSImage de destination et de sauvegarder ensuite.
  • AliGatorAliGator Membre, Modérateur
    18:35 modifié #5
    dans 1192796066:

    On doit pouvoir, mais dans ce cas il ne faut pas utiliser les méthodes Cocoa...
    Il faut lire un bout du fichier, travailler dessus, lire un autre bout etc.
    A la limite, mais ça sous-entend de connaà®tre le codage du fichier, donc si on veut pouvoir ouvrir n'importe quelle image de cette manière, il faut implémenter ce genre de code bas niveau pour chaque format d'image. Et en plus ce n'est pas forcément appliquable pour tous les formats d'image, selon les algorithmes de chacun !

    On pourrait par exemple faire une mise à  l'échelle 1/2 sur une image stockée au format JPEG, décoder chaque macrobloc 16x16 et ses voisins, faire la réduction du macrobloc (en tenant compte du voisinage donc pour les effets de continuité) pour obtenir un pseudo-macrobloc 4x4, puis passer au MB suivant... Et dropper les macroblocs qui ne sont plus utiles au fur et à  mesure... déjà  y'a du boulot pour un truc comme ça... et encore c'est que pour le JPEG. Après faut faire le même genre en PNG, en TIFF, et j'en passe...
    Donc à  mon avis c'est pas trop envisageable, ou alors faut vraiment en avoir l'utilité, genre un soft dédié à  la manipulation d'images aux résolutions disproportionnées genre 9000x9000 ou pire
  • schlumschlum Membre
    18:35 modifié #6
    Oui, c'est sûr, c'est assez extrême et il faut avoir besoin de cette optimisation pour travailler comme ça !
    Mais je pense aussi aux gros formats comme les RAW etc.
  • lpidenislpidenis Membre
    18:35 modifié #7
    bonjour,
    pour ma part, la méthode suggérée par psychoh13, me semble la plus simple, maintenant j'ai lu que (mais je n'ai pas essayé, pas encore...) que CoreImage pouvait substituer avantageusement NSImage pour ce genre d'opération, car il est susceptible de faire travailler les GPU (cartes graphiques), etc...
    Ceci dit dans le cas du post initial, (images dans une NSMatrix), je recommanderais de mettre en place une NSRelasePool,, de manière à  libérer la mémoire après chaque conversion, c'est souvent là  que cela coince, si on lance des resize en série, on risque de saturer la ram et de faire swapper le système ce qui ralentit fortement l'opération. J'ai déjà  rencontré le cas et ca fait une grosse différence!
    Denis
Connectez-vous ou Inscrivez-vous pour répondre.