Bindings et stockage des images

ideaidea Membre
18:26 modifié dans API AppKit #1
Bonjour
j'ai créé une application qui me sers de base de données pour gérer mes films (dvd et divx). J'utilise coredata et les bindings. J'ai la possibilité de rajouter la jacquette pour chaque film par l'intermédiaire d'un drag and drop sur un NSImageView. J'ai pas de souci a ce niveau la. grace au bindings ca enregistre mes images dans le .xml. Mais le probleme vient du fait que mon xml grossi énormement a chaque ajout d'image. Je suppose qu'il enregistre les images sans les compressé ni rien. Ce que je voudrais pouvoir faire c'est compresser ces images au niveau de l'enregistrement. Faut t'il que je passe par un ValueTransformer spécifique?
Merci

Réponses

  • Eddy58Eddy58 Membre
    18:26 modifié #2
    Je pense qu'enregistrer le chemin de l'image est plus approprié. :)
  • ideaidea Membre
    18:26 modifié #3
    un peu comme ils disent sur cette page :
    http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/Tasks/images.html#//apple_ref/doc/uid/20002300
    j'ai pas encore tout compris en le lisant. je vais le relire plus attentivement...
  • schlumschlum Membre
    avril 2007 modifié #4
    - (NSData *)TIFFRepresentationUsingCompression:(NSTIFFCompression)comp factor:(float)aFloat
    


    dans 1177154227:

    Je pense qu'enregistrer le chemin de l'image est plus approprié. :)


    Pas forcément... Si on veut maintenir une cohérence, il faut les copier quelque-part, et dans ce cas, autant les compresser dans la base.
  • Eddy58Eddy58 Membre
    18:26 modifié #5
    Oui mais bonjour la taille du xml, je pense qu'il est plus correcte de copier toutes les images dans un file wrapper et aller récupérer dedans ce qu'on a besoin ensuite, ça évite d'encombrer la mémoire en images inutiles en chargeant un xml énorme. :)
  • schlumschlum Membre
    18:26 modifié #6
    dans 1177188482:

    Oui mais bonjour la taille du xml, je pense qu'il est plus correcte de copier toutes les images dans un file wrapper et aller récupérer dedans ce qu'on a besoin ensuite, ça évite d'encombrer la mémoire en images inutiles en chargeant un xml énorme. :)


    Tiens, ça m'amène à  une question... Comment sont stockés les blobs en XML ?
    Vous allez me dire "entre <data> et </data>", mais s'il y a un "</data>" dans le blob... ?

    Enfin si Apple a bien fait le truc et stocké la taille (par exemple), on ne perd pas plus en performance qu'avec des fichiers. Je dirais même moins puisqu'il y a un seul file descriptor à  ouvrir au lieu de plein.
  • ideaidea Membre
    18:26 modifié #7
    euh c'est quoi un blob?
    dans mon xml l'image a l'air d'etre insérer entre 2 balises attributes et il précise juste avant que c'est du binary.

  • schlumschlum Membre
    18:26 modifié #8
    dans 1177230151:

    euh c'est quoi un blob?
    dans mon xml l'image a l'air d'etre insérer entre 2 balises attributes et il précise juste avant que c'est du binary.


    Un blob c'est justement des données binaires, mais apparemment en XML il ne stocke ça pas vraiment en binaire, mais en hexadécimal... Donc pas de problème pour trouver la balise finale, mais effectivement dans ce cas ça peut poser des problèmes d'optimisation.
  • ideaidea Membre
    18:26 modifié #9
    donc je vais m'orienter vers un fileWraper. Par contre je vois pas trop coment faire a partir de mon coreData et de mes bindings. vous auriez pas une piste pour que je me lance?
    a plus
  • ideaidea Membre
    18:26 modifié #10
    Bon globalement si j'ai bien compris tout ce que j'ai pu lire, c'est pas trop possible avec core data.
  • schlumschlum Membre
    18:26 modifié #11
    dans 1177305742:

    Bon globalement si j'ai bien compris tout ce que j'ai pu lire, c'est pas trop possible avec core data.


    À mon avis, ce que Eddy58 pensait, c'était enregistrer le "path", pas la classe NSFileWrapper  ;)
    C'est à  dire une chaà®ne UTF-8...
  • AliGatorAliGator Membre, Modérateur
    18:26 modifié #12
    BLOB = Binary Large OBject ; ils sont enregistrés en hexa dans le plist ou le XML, ce qui est logique puisque c'est du binaire donc mieux vaut l'encoder... mais de toute façon même si c'était de l'ascii non encodé (données brutes), elles aurait été alors dans un <[CDATA[...]]>.

    Je vote aussi pour la solution d'externaliser les images pour ce genre de problème. Ca évite d'avoir un fichier bien lourd, à  charger comme à  stocker, et plus facile à  maintenir au final. Après que les images soient dans un fileWrapper ou juste dans un dossier spécifique de "Application Support" (ce qui me paraà®t presque plus simple), du moment qu'on a une référence quelquepart...

    Par contre dans ce cas cela pourra être bien de proposer à  terme du coup une fonction "exporter la base de données" qui wrappe le plist + le dossier "Application Support" (enfin surtout les images associées au plist de la base) dans un seul fichier (que ce soit juste un zip de tout ça, ou un fileWrapper, ou autre) pour que l'on puisse déplacer ou sauvegarder la base facilement. Mais ça tu peux le faire dans un second temps.
  • schlumschlum Membre
    18:26 modifié #13
    dans 1177322952:

    BLOB = Binary Large OBject ; ils sont enregistrés en hexa dans le plist ou le XML, ce qui est logique puisque c'est du binaire donc mieux vaut l'encoder... mais de toute façon même si c'était de l'ascii non encodé (données brutes), elles aurait été alors dans un <[CDATA[...]]>.


    Pour moi, ce qui aurait été logique, ça aurait été d'encoder la taille au début, puis en brut. C'est la solution la plus optimisée pour le lire.
    Après, c'est sûr que c'est moins pratique pour la lecture des plist "à  la main".


    Je vote aussi pour la solution d'externaliser les images pour ce genre de problème. Ca évite d'avoir un fichier bien lourd, à  charger comme à  stocker, et plus facile à  maintenir au final. Après que les images soient dans un fileWrapper ou juste dans un dossier spécifique de "Application Support" (ce qui me paraà®t presque plus simple), du moment qu'on a une référence quelquepart...


    Dans mon boulot actuel, je gère une base de données SQLite de plusieurs centaines de Mo. Une petite image compressée en jpg c'est rien pour une BDD.
    Après, ça dépend de la philosophie qu'on veut appliquer...
  • ideaidea Membre
    18:26 modifié #14
    bien je m'oriente vers ta solution AliGator. je vais ajouter un IdImage a mon core data model. ajouter une nouvelle classe pour mes images, pour charger et enregistrer mes images en jpg dans un dossier a part, et je fais le lien entre l'image et l'IdImage, pour afficher la bonne image. J'ai bon dans ma démarche?
    j'ai remarqué que dans mon .xml chaque enregistrement de film a un ID : <object type="MOVIE" id="z200">
    puis-je récupéré ce ID d'une quelconque manière?
  • AliGatorAliGator Membre, Modérateur
    18:26 modifié #15
    dans 1177323424:

    Pour moi, ce qui aurait été logique, ça aurait été d'encoder la taille au début, puis en brut. C'est la solution la plus optimisée pour le lire.
    Après, c'est sûr que c'est moins pratique pour la lecture des plist "à  la main".
    Oui mais non car avec les "caractères invisibles" il suffirait alors d'ouvrir un plist avec un éditeur de texte basique et de resauver le plist et à  tous les coups tu perds des caractères et donc des informations et ça corrompt toutes tes données.
    Donc il faut un minimum encoder : écriture hexa ou base64, mais pas brut, pas dans un fichier (plist) qui à  la base est du texte (il existe un format de plist binaire, mais ce n'est qu'une compression de son alterégo textuel, et on peut passer d'un format à  l'autre)

    Dans mon boulot actuel, je gère une base de données SQLite de plusieurs centaines de Mo. Une petite image compressée en jpg c'est rien pour une BDD.
    Ben oui là  c'est logique, c'est une base SQLite. C'est fait pour gérer des grosses quantités de données, et ça gère aussi les données binaires (avec des BLOB justement) très bien. Mais là  c'est géré avec du XML, ce qui n'a rien à  voir tant quant à  la quantité et taille des données manipulables (c'est bien plus lourd de charger un gros XML, format qui n'est pas spécialement dédié à  contenir des données binaires et surtout des gros objets, même s'il peut il n'est pas optimisé et fait pour).
    De plus, avec une base SQLite, le chargement est sélectif (tu ne charges pas toute la base d'un coup, tu effectue des requêtes sur la base) alors que le XML tu le charges en entier en mémoire. Donc un plus gros XML va être plus lourd à  gérer, alors que sinon les bases de données sont tout à  fait indiquées pour les grandes quantitées de données, volumineuses ou non.
  • schlumschlum Membre
    18:26 modifié #16
    dans 1177333939:

    dans 1177323424:

    Pour moi, ce qui aurait été logique, ça aurait été d'encoder la taille au début, puis en brut. C'est la solution la plus optimisée pour le lire.
    Après, c'est sûr que c'est moins pratique pour la lecture des plist "à  la main".
    Oui mais non car avec les "caractères invisibles" il suffirait alors d'ouvrir un plist avec un éditeur de texte basique et de resauver le plist et à  tous les coups tu perds des caractères et donc des informations et ça corrompt toutes tes données.
    Donc il faut un minimum encoder : écriture hexa ou base64, mais pas brut, pas dans un fichier (plist) qui à  la base est du texte (il existe un format de plist binaire, mais ce n'est qu'une compression de son alterégo textuel, et on peut passer d'un format à  l'autre)


    C'est pour ça que je parlais de philosophie au dessus... À mon avis, pour une application de ce genre, il aurait dû utiliser un format SQLite avec CoreData plutôt qu'un format XML  ;) (surtout s'il compte gérer plus d'une centaine d'enregistrements...)
    Le XML n'est pas "optimisé" pour contenir du binaire (qui dit hexadécimal dit recherche de la balise finale et conversion ; ça prend du temps).
  • Eddy58Eddy58 Membre
    18:26 modifié #17
    dans 1177308724:

    À mon avis, ce que Eddy58 pensait, c'était enregistrer le "path", pas la classe NSFileWrapper  ;)
    C'est à  dire une chaà®ne UTF-8...

    Initialement en effet je parlais seulement du path, mais si l'utilisateur efface des images le système est bancale. Donc ensuite je pensais effectivement à  la classe NSFileWrapper pour enregistrer le xml et stocker une version light des images le tout dans un seul fichier. Après, comment faire ça avec Core Data, je ne l'ai jamais utilisé donc je peux pas dire, en ce qui concerne les bindings un value transformer me parait tout indiqué, il y a une bonne base de départ dans le lien proposé plus haut par idea.

    Mais avec Core Data ta suggestion d'utiliser SQlite est encore le plus pratique en effet. :o
  • ideaidea Membre
    18:26 modifié #18
    Merci a tous pour ces conseils
    je vais passer mon core data en en registrement SQLite. pour la version 1 du logiciel, et pour mon utilisation personnel ca suffira bien. Si je fais une version 2, je partirai dans une voie plus programmatique, ou je serai plus libre d'enregistrer comme bon me semble.
  • cargocargo Membre
    18:26 modifié #19
    Concernant les images dans CoreData, il est préférable de créer une entité à  part pour les stocker, que tu relies en one-to-one à  ton entité concernée (ex: Employee <-> Employee_Photo ).
    Ceci permet de les charger en mémoire uniquement lorsque c'est nécessaire (au moment où la relationship est appelée).
    Jette un oeil sur la doc Apple, en particulier sur les accesseurs aussi.


    Si je fais une version 2, je partirai dans une voie plus programmatique, ou je serai plus libre d'enregistrer comme bon me semble.


    Attention à  la compatibilité, ça me paraà®t être un point essentiel avec l'utilisation de CoreData. Ne serait-ce qu'une modification du modèle et hop, les fichiers de la version 1 ne sont plus compatibles avec la version 2.
    Je pense qu'il faut prendre le temps de modéliser l'application en pensant aux fonctionnalités à  venir, et prévoir un export ou un copier-coller des données sous un format qui permettra des les ré-importer ensuite dans une autre version.

    Autre chose, je pense qu'il est bon de se préserver 2 formats possibles d'enregistrement des données, SQlite et XML. En cas de corruption, de dysfonctionnement de la base SQlite par exemple, on peut récupérer un backup XML qui est un format plus standard, plus "lisible" aussi.

    Voilà ... sinon je pense que SQlite est suffisemment robuste pour stocker des images en grande quantité pour peu qu'on les optimise afin d'alléger le fichier final.
    Si c'est pour stocker la photo d'un contact ça va, si c'est pour stocker des travaux de print A5 à  300dpi au format .psd, il faut faire autrement.

    "Supports databases up to 2 tebibytes (241 bytes) in size."
    "Strings and BLOBs up to 2 gibibytes (231 bytes) in size."
    C'est les chiffres théoriques bien sûr, il faut voir la pratique après :
    "In practice, you should try to keep your SQLite databases below 100 gigabytes to avoid performance problems."
    > www.sqlite.org/

  • schlumschlum Membre
    avril 2007 modifié #20
    Yep 

    À noter qu'on peut changer son modèle en apportant des nouveautés si on gère la conversion à  la volée des anciens formats... C'est ce que font les éditeurs en général  ;)

    "In practice, you should try to keep your SQLite databases below 100 gigabytes to avoid performance problems."

    Effectivement... C'est déjà  énorme ; ça laisse de la marge :D

    Comme l'a dit plus haut AliGator, SQLite ne charge pas tout le fichier, mais est capable de se positionner au bon endroit pour lire ce qui l'intéresse, donc c'est pas parce qu'on a une base de 4Go qu'on perd énormément en performance.

    Après, c'est sûr qu'il vaut mieux éviter de stocker des images de plus de 2Mo :o Si on gère ce genre d'image, une gestion à  la "iPhoto" s'impose (copie / placement des images dans une architecture triée au niveau du FileSystem)
  • dsprundsprun Membre
    18:26 modifié #21
    Attention : le formatage des données avec XML est surtout fait pour communiquer entre applications.

    Exemple : IPhoto et son fameux fichier XML qui permet aux développeurs de lier dans leur application une vue sommaire du contenu de la base de photos sur votre Mac.

    Exemple : les données reçues ou envoyées par un SWF ( Flash , Flex) d'une base de données genre mYSQL ou autre. C'est un script PHP qui génère ce XML à  partir d'une requête vers la base de données.

    Exemple : MXML qui permet de décrire les objets (composants) pour le compilateur.

    etc.

    Pour résumer , un langage est fait pour communiquer. En informatique , chaque langage est adapté à  un type d'information. Faites bien votre choix avant de réaliser votre fonction .

Connectez-vous ou Inscrivez-vous pour répondre.