NSImageRep, vImage

ChachaChacha Membre
22:10 modifié dans API AppKit #1
Bonjour,

Pour mon appli de mozaà¯que magique (cf projets d'application), je me suis penché sur l'analyse d'images en Cocoa (histogrammes pour l'instant). Cependant, NSImage est plutôt une abstraction, tandis que les données sont dans des NSImageRep.
Or, la doc d'Apple n'est pas très claire, il me semble, sur l'utilisation de ces NSImageRep. Voici toute une tripotée de questions plus ou moins liées entre elles, pour lesquelles j'implore humblement tout initié de m'instruire.
-Quand je charge une image, lui est-il associé une seule ou plusieurs représentations ?
-Comment sont elles choisies, ou autrement dit, ai-je un peu de contrôle dessus ?
-La représentation choisie dépend-elle du device graphique ou de l'image ?
-Si je veux que toutes les images de mon appli soient en RGB entrelacé sans canal alpha (24 bits), dois-je vérifier/convertir chaque image, ou puis-je imposer une représentation commune à  l'avance ?
-Pour créer/modifier une représentation, suffit-il de modifier les attributs d'une représentation, ou dois-je en construire une de toutes pièces ? Si je dois la construire, comment la "remplir" de pixels ?
-Ai-je raté quelque chose, ou n'y a-t-il pas d'intermédiaire pour créer facilement des vImage_Buffer à  partir de NSImage ou NSImageRep ? Comment faire ça simplement, sachant qu'il faut, je pense vérifier le planar, le alpha, le bps et le bpp ?

Je vais arrêter les questions pour le moment, sachant que j'en ai d'autres, mais qui peuvent découler des premières réponses.

Merci d'avance !

+
Chacha

Réponses

  • BruBru Membre
    22:10 modifié #2
    dans 1107939152:

    -Quand je charge une image, lui est-il associé une seule ou plusieurs représentations ?


    Oui, toutes les représentations sont créées. Ce n'est pas clairement dit dans la doc Apple, mais cela est évoqué dans la doc sur initWithContentsOfFile de NSImage.

    citation :
    "[...]After finishing the initialization, this method returns an initialized object. However, if at least one image representation can't be created from the contents of the specified file, the receiver is freed, and nil is returned."

    Donc si l'une des représentations n'a pu être créée lors de l'initialisation, la méthode échoue (renvoie nil) : il y a donc bien tentative de création des représentations au chargement de l'image.

    .
  • BruBru Membre
    22:10 modifié #3
    dans 1107939152:

    -Comment sont elles choisies, ou autrement dit, ai-je un peu de contrôle dessus ?
    -La représentation choisie dépend-elle du device graphique ou de l'image ?


    Tu peux accéder individuellement à  chaque représentation via la méthode representations de NSImage qui te retourne un NSArray des représentations.

    Mais le système peut déterminer de lui même laquelle est la meilleure pour effectuer son rendu. La sélection est indiquée par Apple dans cette documentation.

    Cette sélection passe par l'utilisation de la méthode bestRepresentationForDevice: de NSImage qui retourne la représentation la plus fidèle en fonction des paramètres passés dans le NSDictionary par rapport aux propriétés de l'image.

    .
  • BruBru Membre
    22:10 modifié #4
    dans 1107939152:

    -Si je veux que toutes les images de mon appli soient en RGB entrelacé sans canal alpha (24 bits), dois-je vérifier/convertir chaque image, ou puis-je imposer une représentation commune à  l'avance ?


    A chaud, je te dirais que chaque type d'image produit son propre NSBitmapImageRep, en fonction des spécificités de chaque format d'image. Par exemple, un tiff avec couche alpha va produire un bitmapRep avec un plan "canal alpha", alors qu'un jpeg n'aura pas ce plan...

    Soit, tu décides de garder ce imageRep en n'utilisant que les élements communs à  chaque image, soit tu créés un imageRep de toute pièce en utilisant les données issues du imageRep d'origine, tout en imposant un format  précis. Dans ce 2ème cas, la piste pourrait être d'utliser le format tiff comme format "commun" à  tous les autres, car Apple fournit par défaut une représentation basée sur ce format, quelque soit l'image en entrée (méthode TIFFRepresentation de NSBitmapImageRep).

    .
  • BruBru Membre
    22:10 modifié #5
    dans 1107939152:

    -Pour créer/modifier une représentation, suffit-il de modifier les attributs d'une représentation, ou dois-je en construire une de toutes pièces ? Si je dois la construire, comment la "remplir" de pixels ?


    Tu ne peux pas modifier une NSImageRep une fois créée (c'est un objet imutable). Le seul salut passe par par la création d'une nouvelle imageRep en utilisant les données de l'originale (via la méthode initWithBitmapDataPlanes:pixelsWide:... de NSBitmapImageRep).

    Les données bitmap d'une image sont accessibles via plusieurs méthodes de NSBitmapImageRep :
    bitmapData
    getBitmapDataPlanes: (dans le cas d'une représentation sur plusieurs plans)

    .
  • ChachaChacha Membre
    22:10 modifié #6
    Jamais en retard sur les coups de main, le Bru, merci beaucoup !

    Je commence d'y voir un peu plus clair dans les NSImageRep, mais je ne trouve pas ça très pratique. En fait, ce qui me gêne, c'est l'absence de pont entre les NSImageRep eux-mêmes, et vers les vImage_Buffer. C'est pour cela que je cherchais à  faire des conversions à  la volée, histoire de factoriser un peu de code. En effet, il faut vraiment, apparemment, tout faire à  la main pour en bénéficier, et c'est cela que j'avais du mal à  admettre. Mais bon, passons. Il est vrai que se tourner vers l'optimisation dès le début, c'est mal, mais en même temps je ne peux pas ignorer le fait que je vais sûrement m'en servir, donc autant baliser le chemin.

    Sinon, j'aurais bien encore deux remarques à  faire, demandant confirmation:
    -Dans vImage, une image est dite "Planar" quand elle n'a qu'un seul canal (PlanarF et Planar8), et non Planar si elle a 4 canaux (RGBA FFFF ou 8888). Or, il me semble que c'est la terminologie inverse qui est utilisée dans les NSImagRep : Planar signifie qu'il y a plusieurs canaux : c'est pas bien normal, ça, non ?

    -Dans le getBitmapDataPlanes, je récupère... 5 canaux ! Je veux bien récupérer R, G, B et A, mais honnêtement, c'est quoi le dernier ? Ce n'est pas dit dans la doc !

    Voilà , sur ces considérations, à  plus tard et merci encore.

    Chacha
  • BruBru Membre
    22:10 modifié #7
    dans 1107958238:

    Sinon, j'aurais bien encore deux remarques à  faire, demandant confirmation:
    -Dans vImage, une image est dite "Planar" quand elle n'a qu'un seul canal (PlanarF et Planar8), et non Planar si elle a 4 canaux (RGBA FFFF ou 8888). Or, il me semble que c'est la terminologie inverse qui est utilisée dans les NSImagRep : Planar signifie qu'il y a plusieurs canaux : c'est pas bien normal, ça, non ?
    -Dans le getBitmapDataPlanes, je récupère... 5 canaux ! Je veux bien récupérer R, G, B et A, mais honnêtement, c'est quoi le dernier ? Ce n'est pas dit dans la doc !


    Planar, ça correspond au stockage des différentes composantes d'un pixel dans une image.

    Dans un espace colorimétrique RGB, effectivement, il n'y aurait que 4 "planars" (rouge, vert bleu et alpha). Mais si tu es dans l'espace CMYK, avec la couche alpha, ça fait bien 5 "planars" à  utiliser (cyan, magenta, jaune, noir et alpha).

    Quand tu crées ton nouveau NSBitmapImageRep via la méthode initWithBitmapDataPlanes:..., tu dois spécifier (paramètre colorSpaceName:) le type d'espace colorimétrique dans lequel tu veux travailler.

    Mais, tu peux tout aussi travailler avec un seul plan (les composantes du pixel se suivent). Dans ce cas, tu dois mettre le paramètre isPlanar: à  NO.

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