Lire/relire/switcher les bits individuels d'une bitmap

berfisberfis Membre
avril 2014 modifié dans API AppKit #1

Bonjour,


 


J'écris "pour m'amuser" différentes implémentations du "Jeu de la vie" de Conway. Pour l'instant j'en ai deux, la première sous-classant les NSCell d'une NSMatrix et la seconde en sous-classant NSView et utilisant Quartz sur la base d'un tableau C. Il va de soi que la seconde est plus rapide (quatre fois environ).


 


Je me demandais s'il serait possible de créer une troisième version faisant appel à  la manipulation individuelle des bits d'une bitmap (noir et blanc) puis à  son affichage (quitte à  zoomer un peu), mais je n'ai rien trouvé de probant dans la doc.


 


Cela dit, j'ai peut-être mal cherché, sans compter que l'accès et la manipulation individuelle des bits n'est pas si rapide ou peu pratique. Mais j'aimerais faire l'essai.


 


Quelqu'un peut-il me dire où regarder?


Mots clés:

Réponses

  • ca fait longtemps que je n'ai pas touché à  ce genre de chose (du temp de NSBitmapImageRep), mais je chercherai du côté de CGBitmapContextGetData


     


    Et pour ne pas trop compliquer je partirais d'une image existante (par exemple d'un carré blanc au format png).


     


    Denis 


  • MalaMala Membre, Modérateur


    Cela dit, j'ai peut-être mal cherché, sans compter que l'accès et la manipulation individuelle des bits n'est pas si rapide ou peu pratique. Mais j'aimerais faire l'essai.




    L'accès direct aux pixels pas si rapide?  ???

  • @Mala : Ben j'ose espérer qu'il y aurait un avantage côté rapidité  ^_^


     


    @ Denis : Mes recherches m'ont effectivement mené à  NSBitmapImageRep et à  ses getPixel:atX:y: / setPixel:atX:y:... Je vais encore regarder du côté de Core Graphics...


     


    En tout cas merci!


  • MalaMala Membre, Modérateur
    avril 2014 modifié #5


    @ Denis : Mes recherches m'ont effectivement mené à  NSBitmapImageRep et à  ses getPixel:atX:y: / setPixel:atX:y:... Je vais encore regarder du côté de Core Graphics...




    getPixel:atX:y et cie à  proscrire. Niveau perfs, çà  oui c'est catastrophique.

     

    Pour des performances optimales, il faut taper directement sur la matrice de pixels via bitmapData pour passer directement en revue le buffer des pixels d'une image.



  •  


    getPixel:atX:y et cie à  proscrire. Niveau perfs, çà  oui c'est catastrophique.

     

    Pour des performances optimales, il faut taper directement sur la matrice de pixels via bitmapData pour passer directement en revue le buffer des pixels d'une image.

     




     


    le getPixel est très lent car les images sont compressées et il faut les "rastériser", donc d'une manière générale, faut regrouper toutes les opérations que l'on a y faire, récupérer le vecteur de pixels, et les effectuer dans une même itération...


     


     Si @berfis n'a pas eu l'occasion de pratiquer ce genre de manipe, un petit conseil, utiliser un struct pour manipuler les différents couleurs, c'est plus facile, mais c'est comme dans tout (ou presque) les cas particuliers sont toujours plus simples, par exemple des images à  8 bits par couleur, en mode meshed en RVB  (comme dans un jpeg par exemple). Il faut garder à  l'esprit que la rastérisation prend beaucoup de place en mémoire, donc si l'image est de grande taille car peut rapidement devenir un problème. L'idéal serait de pouvoir modifier des pixels directement sur le raster qui sert à  l'affichage (pour éviter d'en avoir deux), je ne me suis pas penché sur la question, et je ne sais pas si il est possible de faire cela sans passer par OpenGL?

  • MalaMala Membre, Modérateur
    avril 2014 modifié #7

    Dans MarScaper HDR, j'utilise un système de tuiles avec une compression maison pour manipuler mes images et limiter l'usage mémoire. Les données sont toutes converties en amont comme ça le moteur de rendu n'a pas à  se soucier de l'encodage des pixels des images de départ.


     


    J'ai testé OpenGL mais j'ai jamais réussi à  manipuler les textures en direct. Tous les codes d'exemple trouvés sur le net passaient par un remplacement de texture (donc double buffer qui n'avance à  rien) ou ne marchaient pas. :/ Il faut aussi faire attention aux limitations graphiques (tailles de texture max). Du coup, en dessinant directement un NSBitmapImageRep avec un système de cache pour ne pas le remplacer à  chaque fois, je suis resté sur NSBitmapImageRep qui me permet déjà  de dépasser les 150 fps (dans mon cas avec mes  calculs de tone mapping inclus) tout en gérant correctement les profils colorimétriques du système.


  • je suis distrait... je n'avais pas fait attention que c'était sur OSX (je pensais à  iOS qui ne dispose pas d'autant de mémoire ni des mêmes classes) effectivement NSBitmapImageRep ca fonctionne assez bien.J'espère que @berfis nous donnera un retour intéressant :-)

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