IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

Afficher un image dynamiquement pixel par pixel


Sujet :

Qt

  1. #1
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut Afficher un image dynamiquement pixel par pixel
    Bonjour à tous,

    Voilà j'essaye d'utiliser Qt pour faire une simple form affichant une image, puis lancer un traitement sur l'image assez long pendant lequel je veux afficher les résultats en modifiant les pixels un à un à chaque fois que le traitement de l'image l'a calculé.

    Cela me permet de "debugger" mon algorithme. Le côté "temps réel" (bien que ce n'en soit pas vraiment au sens strict) est trés important car je veux voir la dynamique du calcul.

    Je m'y perd un peu entre les différents moyen d'afficher une image (bitmap dans un label, QtPainter, BlitMapping, double buffering, ...) quel est le meilleur moyen pour éviter le flicking étant donné mes besoins ?

    Merci.

  2. #2
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Salut,

    Tu n'auras pas à souffrir de flicking; Qt4+ (quoique tu n'as pas spécifié ta version, c'est laquelle?) offre un mécanisme de double buffering par défaut sur la majorité des plateformes.

    Je me sers de QLabel+QPixmap pour les images fixes, ce qui n'est pas ton cas donc
    QPixmap est optimisé pour l'affichage, alors que QImage est optimisé pour le traitement. Quoiqu'il arrive, tu devras créer donc 2 QImage: le courant et le support de travail, ensuite tu en fais un QPixmap pour affichage.
    Selon la taille et les fonctions à supporter, je te conseillerais de créer un widget personnalisé dérivant de QAbstractScrollArea (suggestion seulement )

  3. #3
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Merci pour la réponse.

    Je vais suivre tes conseils. Pour le QImage, comment je peux faire pour modifier un pixel à la fois ? Je passe par un QPainter (ce le seul objet Qt que j'ai trouvé qui à une méthode DrawPoint) ? Ou est-ce que je peux avoir directement accès aux pixels par un pointeur sur une zone mémoire ?

  4. #4
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    QImage::pixel() et QImage::setPixel(). Tu peux éviter le QPainter pour ces opérations

    Tu as aussi QImage::bits() qui correspondra probablement plus à ce que tu cherches?

  5. #5
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    setPixel() me va trés bien. Je vais m'orienter vers cette solution simple.

    Un début de piste pour l'enchainement des refresh entre :

    QImage (buffer) -> QImage (courant) -> QPixmap (conversion) -> QLabel ?

    C'est à dire qu'elles méthodes je dois choisir étant donné mon pb. (il y en à tellement) ?

    Plus ça va, plus je me demande si c'est pas un peu lourd comme châine de traitement, alors que je ne change qu'un pixel à la fois ! (On ne peut pas dessiner directement sur le Canvas, pour un pixel ?)

  6. #6
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Citation Envoyé par mchk0123
    (On ne peut pas dessiner directement sur le Canvas, pour un pixel ?)
    Euh, là, t'en as pas assez dit alors
    Si tu parles de QCanvas, tu es sous Qt3, ça peut changer des choses (comme le problème du double buffering précisé dans le 1er post). De plus si tu utilises un QCanvas, tu n'as pas besoin d'un QLabel, mais soit d'une classe dérivant de QCanvasItem.

    Alors, quelle est ta situation exacte?

  7. #7
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Je suis bien sous Qt4.2.3 mingw mais ce que je demande c'est si passer par 4 objets différents (2x QImage, QPixmap, QLabel) avec une recopie de l'image entre chaque ça ne risque pas d'être lent : car je veux vraiment voir les pixels s'afficher les 1 aprés les autres.

    Donc c'est pour ça que j'avais aussi pensé à QCanvas (plus rapide ?) mais que j'avais laisser tomber car je n'arrivais déjà pas à afficher les pixels (l'image restait toujours noire).

  8. #8
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Merci pour ces précisions.

    Citation Envoyé par mchk0123
    Je suis bien sous Qt4.2.3 mingw mais ce que je demande c'est si passer par 4 objets différents (2x QImage, QPixmap, QLabel) avec une recopie de l'image entre chaque ça ne risque pas d'être lent : car je veux vraiment voir les pixels s'afficher les 1 aprés les autres.
    Justement, si tu veux les voir s'afficher, tu auras même intérêt à foutre un QTimer avec un timeout de quelques dizaines/petites centaines de ms pour gérer ton traitement
    Il n'y a pas d'accés direct à la zone graphique d'un widget, donc tu es obligé de procéder soit:
    > de la façon que tu as décrit (adapté jusqu'à certaines tailles)
    > soit, plus court et plus propre: 2x QImage, et tu l'envoies à un widget perso qui dessine directement grâce à QPainter::drawImage dans ta réimplémentation du paintEvent.
    Citation Envoyé par mchk0123
    Donc c'est pour ça que j'avais aussi pensé à QCanvas (plus rapide ?) mais que j'avais laisser tomber car je n'arrivais déjà pas à afficher les pixels (l'image restait toujours noire).
    QCanvas est déprécié depuis Qt4, et est remplacé depuis la 4.2 par les classes QGraphics* (View/Scene/...)
    Mais n'est vraiment pas adapté à ce que tu veux.

  9. #9
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Citation Envoyé par IrmatDen
    > soit, plus court et plus propre: 2x QImage, et tu l'envoies à un widget perso qui dessine directement grâce à QPainter::drawImage dans ta réimplémentation du paintEvent.
    Compris pour le paintEvent + drawImage.
    Pour le QTimer, l'idée est trés bonne, je vais seulement le déplacer un peu : un sleep() dans mon moteur de traitement d'image (multi-threadé par rapport à Qt).

    Dés que j'ai un exemple de code (s'il ne marche pas) je reviens pour le poster.

    Par contre je ne vois pas encore l'intérêt d'avoir 2 QImage s'ils sont tous les deux de type back-buffer ? 1 QImage ne suffirais pas ?

  10. #10
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Citation Envoyé par mchk0123
    Par contre je ne vois pas encore l'intérêt d'avoir 2 QImage s'ils sont tous les deux de type back-buffer ? 1 QImage ne suffirais pas ?
    Non non non! Soit j'ai pas assez insisté sur ce point, soit tu as mal compris (ou surement un mélange des 2 ), mais il n'y a *que*les widgets qui ont un système de double buffer. Un QImage ne contiennent qu'une et une seule image. D'où la nécessité d'avoir 2 instances selon ton travail; je pense particulièrement à des calculs basés sur des matrices de pixel, et où l'image sur laquelle tu travailles doit donc être une autre que celle où tu dessines (imagine le décalage sinon )

  11. #11
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Arf ... je crois avoir compris.

    La première QImage sert de buffer mémoire (réprésentation mémoire).

    Je ne penses pas en avoir besoin, car avec ma bibliothèque de traitement d'image j'ai déjà une matrice allouée de m x n de pixels, ce qui serait en double avec la première QImage.

    Je penses donc que je vais utiliser qu'une seule QImage.

  12. #12
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Oui, c'est bien ça, et dans ces conditions tu n'as effectivement pas besoin de 2 images. Sujet résolu donc?

  13. #13
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Bon ça y est ça fonctionne !

    Par contre j'ai été obligé de déplacer le refresh à l'intérieur d'un timer de 41ms (environ 24 img/s, comme à la télé ).

    Au début je l'avais fait pour chaque pixel modifié, bonjour le flickering !

    Je considère le sujet résolu. Par contre dommage de ne pas pouvoir peindre directement sur le canvas sans passer par QImage -> QPixmap -> QLabel. Ca aurait surement accéléré l'affichage.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Points : 93
    Points
    93
    Par défaut
    Citation Envoyé par mchk0123
    Par contre dommage de ne pas pouvoir peindre directement sur le canvas sans passer par QImage -> QPixmap -> QLabel. Ca aurait sûrement accéléré l'affichage.
    Impossible de ne pas passer par la conversion QImage -> Qpixmap dans un toolkit généraliste. Par exemple sur Qt/X11, le QPixmap est sur le serveur X (donc en mémoire vidéo voire sur un autre ordinateur) et QImage est en mémoire normale, directement accessible par le client. Des toolkits comme SDL peuvent court-circuiter ce mécanisme et y gagner en rapidité, mais au dépens de la flexibilité (par exemple affichage distant impossible sous X11).

  15. #15
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Merci pour ces explications.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutante] Moyenner des images pixel par pixel
    Par Krokro00 dans le forum Images
    Réponses: 7
    Dernier message: 31/05/2007, 15h49
  2. Image a remplir Pixel par Pixel, Quel objet utiliser ?
    Par ZbergK dans le forum GTK+ avec C & C++
    Réponses: 5
    Dernier message: 28/02/2007, 21h35
  3. Lecture de fichiers images pixels par pixels
    Par FabHacker dans le forum Langage
    Réponses: 3
    Dernier message: 26/11/2005, 16h12
  4. [ImageMagick] Parcourir une image pixel par pixel
    Par kip dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 05/10/2005, 14h10
  5. [VB6] [Graphisme] Transfert d'image pixel par pixel
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 15/10/2002, 09h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo