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 :

Affichage de grandes images [Graphics View]


Sujet :

Qt

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 41
    Par défaut Affichage de grandes images
    Bonjour,

    J'ai décidé de me mettre à Qt Graphics dans le but de montrer un exemple d'utilisation à mes élèves. J'aimerais coder un prog qui charge une carte topo IGN au 1:25000 de grande taille pour pouvoir faire des zooms et des déplacements. Je l'ai fait mais au chargement c'est très long : je charge toute l'image d'un seul coup. Du coup j'ai jeter un oeil sur le forum et sur le net et il ai dit qu'il faut mettre en place un système de tuiles avec un thread qui s'occupe de charger les tuiles (et un peu plus) pour la vue en cours et d'actualiser ceci quand on déplace.

    Sur le principe/théorie je comprend mais j'ai du mal à voir par quoi commencer et comment procéder concrètement (codage). Habituellement je me débrouille seul mais là je trouve que les exemples du net ne sont pas très précis.

    Comment peut-on récupérer une zone rectangulaire directement dans un fichier image sans charger toute l'image ?
    Comment doit-on gérer les tuiles (tableau 2 dim, QMap, etc.. ) ?
    Comment se passe la demande d'actualisation (Thread) ?

    Voilà je me pose toutes ces questions qui sont peut-être encore un peu vague.

    Si quelqu'un à un tuto plus précis et/ou un exemple de code à me fournir qui ressemble à ce que je veux faire, un peu comme google maps, ce serait très sympa.

    Merci d'avance.

    Edit :
    Bon j'ai commencé à faire le système de tuiles mais j'ai vu que l'on pouvait également utiliser la classe QImageReader et la méthode setClipRect(..).

    Du coup j'ai fait un prog tout simple qui me capture 2 zones de 512*512 chacune dans ma carte topo de 5000*4000 pour ensuite les placer dans ma vue.
    Ma vue fait 512*512, ma scene fait 1536*1536. Mais le problème est lorsque je lis une deuxieme fois dans le QImageReader j'ai une erreur :
    "Unable to read image data". Le code est 4 : QImageReader::InvalidDataError 4 The image data was invalid, and QImageReader was unable to read an image from it. The can happen if the image file is damaged.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    QImageReader reader("./cartes/carte.png");
     
        reader.setClipRect(QRect(0,0,512,512));
        QImage monImage = reader.read();
        if(monImage.isNull())
            qDebug()<<"error image"<<endl;
     
        reader.setClipRect(QRect(512,0,512,512));
        QImage monImage2 = reader.read();
        if(monImage2.isNull())
            qDebug()<<"error image2 : "<<reader.error()<<" / "<<reader.errorString()<<endl;
     
        QPixmap monPixmap = QPixmap::fromImage(monImage);
     
        QGraphicsPixmapItem * itemPixmap = new QGraphicsPixmapItem(monPixmap);
        scene.addItem(itemPixmap);//*/
     
        QPixmap monPixmap2 = QPixmap::fromImage(monImage2);
     
        QGraphicsPixmapItem * itemPixmap2 = new QGraphicsPixmapItem(monPixmap2);
        itemPixmap2->setOffset(512,0);
        scene.addItem(itemPixmap2);//*/
    l me faut créer un deuxeme QImageReader pour faire une deuxième capture....je trouve ça un peu lourd. J'ai certainement du merder quelque part mais où......je ne vois pas.
    Ce code fonctionne mais il est lourd :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    QImageReader reader("./cartes/carte.png");
    
        reader.setClipRect(QRect(0,0,512,512));
        QImage monImage = reader.read();
        if(monImage.isNull())
            qDebug()<<"error image"<<endl;
    
        QImageReader reader2("./cartes/carte.png"); // On doit pouvoir ne pas recréer cet objet !????!!!!?????
        reader2.setClipRect(QRect(512,0,512,512));
        QImage monImage2 = reader2.read();
        if(monImage2.isNull())
            qDebug()<<"error image2 : "<<reader2.error()<<" / "<<reader2.errorString()<<endl;
    
        QPixmap monPixmap = QPixmap::fromImage(monImage);
    
        QGraphicsPixmapItem * itemPixmap = new QGraphicsPixmapItem(monPixmap);
        scene.addItem(itemPixmap);//*/
    
    
        QPixmap monPixmap2 = QPixmap::fromImage(monImage2);
    
        QGraphicsPixmapItem * itemPixmap2 = new QGraphicsPixmapItem(monPixmap2);
        itemPixmap2->setOffset(512,0);
        scene.addItem(itemPixmap2);//*/
    Je ne vois pas comment faire.....

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Salut.
    Déjà, evite les gros edit, car cela passe inaperçu
    Le but est de faire apprendre Qt ou les SIG?
    Tes images ne seront que des png? ou tu veux gérer le maximum de type d'image?
    Tu peux avoir plusieurs type de repère carto?

    Ton utilisation de QImageReader semble approprié. Regarde aussi QPixmapCache

    En générale on utilise un pyramide d'image ou on choisi le niveau en fonction su zoom.

    Pour t'inspirer, tu peux regarde QGis qui est en Qt.

    l me faut créer un deuxeme QImageReader pour faire une deuxième capture....je trouve ça un peu lourd. J'ai certainement du merder quelque part mais où......je ne vois pas.
    Bizarre. Il me semblais que cela marché bien.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 41
    Par défaut
    Citation Envoyé par yan Voir le message
    Salut.
    Déjà, evite les gros edit, car cela passe inaperçu
    Ca marche !
    Citation Envoyé par yan Voir le message
    Le but est de faire apprendre Qt ou les SIG?
    Disons que mes élèves ont un projet de géolocalisation de véhicule et que l'IGN prospose ses cartes gratuitement dans le cadre de l'enseignement. Ils devront donc pouvoir suivre les trajets des véhicules en direct sur une carte, zoomer/dezoomer, déplacer, etc....
    Je voudrais donc dejà savoir comment gérer une grande carte soit par tuiles soit avec QImageReader afin de pouvoir leur expliquer quand ils en seront là. J'avais une préférence pour QImageReader qui m'éviter de découper à l'avance mon image.
    Citation Envoyé par yan Voir le message
    Tes images ne seront que des png? ou tu veux gérer le maximum de type d'image?
    Le png ira très bien au départ.
    Citation Envoyé par yan Voir le message
    Tu peux avoir plusieurs type de repère carto?
    non, je ne pense pas, un seul type de repère sera suffisant.
    Citation Envoyé par yan Voir le message
    Ton utilisation de QImageReader semble approprié. Regarde aussi QPixmapCache

    En générale on utilise un pyramide d'image ou on choisi le niveau en fonction su zoom.
    C'est à dire ? J'ai du mal à suivre le coup de la pyramide d'image .....
    Citation Envoyé par yan Voir le message

    Pour t'inspirer, tu peux regarde QGis qui est en Qt.
    Je vais jeter un oeil mais vu l'ampleur du programme je ne sais pas si je vais réussir à trouver ce que je veux dedans...mais bon je vais voir.
    Citation Envoyé par yan Voir le message
    Bizarre. Il me semblais que cela marché bien.
    Ben ouais moi aussi ça me parait bizarre.

    Merci pour ta réponse. si tu as d'autres pistes à me proposer je suis preneur.

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Une pyramide d'image c'est une suite d'image de plus en plus petite. A chaque niveau tu peux générer des tuiles.
    Le but est de minimiser le nombre de tuile à afficher.
    EN gros une tuile d'un niveau représente les quatre tuiles du niveau supérieur et petite taille.

    Pour le QPixmapCache c'est pour avoir un cache de tuiles. Comme cela tu peux vérifier si la tuile n'est pas déjà charger et l'utiliser ou alors tu charge une nouvelle tuile.
    QImageReader peux t'aider à générer tes tuiles.

    Si ton image fait 1536*1536, elle devrait se charger sans problème. Et tu n'aura pas à faire tout cela. Après cela dépend ce que tu veux leur faire faire.
    Pour aller plus loin, regarde GDal qui permet de lire une grande majorité de carte SIG.

    SI tu as des problèmes de projection sur la carte, regarde la lib proj.4

    Pour QGis, si je me souviens bien, regarde la classe QgsRasterLayer. Tu pourrais aussi leur faire faire un plugin pour GDAL.

  5. #5
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Pour le problème avec QImageReader, je soupconne un problème d'ouverture de fichier qui n'est pas fermé. Une solution : créer soi même le QFile et le fermer après un read et le ré-ouvrir après (j'ai testé, ça fonctionne) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    QFile file("./cartes/carte.png");
    QImageReader reader(&file);
    reader.setClipRect(QRect(0,0,512,512));
    QImage monImage = reader.read();
    if(monImage.isNull())
        qDebug()<<"error image"<<endl;
    file.close();
     
    file.open(QIODevice::ReadOnly);
    reader.setClipRect(QRect(512,0,512,512));
    monImage = reader.read();
    if(monImage.isNull())
        qDebug()<<"error image2 : "<<reader.error()<<" / "<<reader.errorString()<<endl;
    C'est probablement un bug Qt à mon avis (ou tout au moins un comportement étrange)

    EDIT : après vérification dans les sources, en effet, le fichier est ouvert dans read() mais est fermé que dans le destructeur de QImageReader. En cas d'appels multiples à read(), le fichier n'est pas fermé entre 2, donc problème.

    EDIT2 : J'ai oublié de préciser, pour info : il existe un tutoriel sur QPixmapCache, en français : Optimisation avec QPixmapCache (l'article date de 2004 donc le code n'est plus forcement à jour donc à adapter)

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 41
    Par défaut
    Merci à tous les deux pour vos infos. Je vais pouvoir continuer à approfondir tout ça.

    quelque part je suis content d'avoir trouver un "bug" dans Qt ........

    Si j'ai des soucis je reviendrais probablement vers vous.

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

Discussions similaires

  1. PowerPoint - Affichage d'une image en grand clic souris
    Par bend55 dans le forum VBA PowerPoint
    Réponses: 1
    Dernier message: 15/04/2015, 14h35
  2. affichage grande image apres clic sur vignette
    Par Vanessa48 dans le forum Langage
    Réponses: 3
    Dernier message: 06/01/2013, 19h37
  3. Affichage d'une grande image dans un composite SWT
    Par Jibouze70 dans le forum SWT/JFace
    Réponses: 3
    Dernier message: 09/07/2007, 11h51
  4. Affichage d'une très grande image
    Par Exca dans le forum Traitement d'images
    Réponses: 2
    Dernier message: 26/12/2006, 20h26
  5. Affichage d'une grande image découpée
    Par cyril_sy dans le forum SDL
    Réponses: 6
    Dernier message: 03/11/2006, 22h03

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