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

VB.NET Discussion :

Travailler sur une image [Débutant]


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    passionné
    Inscrit en
    Janvier 2016
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : passionné
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2016
    Messages : 22
    Par défaut Travailler sur une image
    bonjour,

    je suis débutant en VB.net, je suis de toute façon un amateur, j'ai commencé avec du basic il y a 20 ans et j'ai essayé de suivre sur mon temps libre les évolutions... je programme de petits jeux pour mon propre usage.

    Je dispose de VB express 2013 (car sous seven VB6 ne fonctionne plus ! )

    Tout cela pour vous demander d'excuser les erreurs de terminologie que je vais probablement faire.

    Je cherche à faire les opérations suivantes :
    ouvrir dans une picture.box une image,
    dessiner sur celle-ci,
    la revoir telle quelle même si d'autres fenêtres viennent la cacher provisoirement ou si je la "scrolle",
    puis recharger cette même image initiale pour faire un nouveau dessin et ainsi de suite plusieurs fois.
    Ce n'est pas un travail "rapide" : l'image ne sera pas modifiée plusieurs fois par secondes, c'est une activité posée.

    je veux que cette image reste affichée comme elle l'était dans "autoredraw" de VB6

    j'ai fouillé et trouvé de solutions :

    voici le code que j'ai essayé d'utiliser

    un bouton lance ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Dim myBitmap1 As New Bitmap("C:\Users\Utilisateur...\image.JPG" 'Je crée un BitMap
    Dim newgraphic1 As Graphics = Graphics.FromImage(myBitmap1) 'je crée un Graphics à partir du BitMap
    newgraphic1.DrawEllipse(mypen, x,y, rayon1, rayon1) ' je dessine sur mon Graphics
    picturebox.image= mybitmap1 'je mets dans une picturebox le résultat
    newgrpahic1.dispose()' je ferme le graphics
    je pensais alors pouvoir faire :
    mais cela efface la picturebox. je comprends pas pourquoi la picturebox ne reste pas affichée, mais bon, j'admets que je ne comprends pas... Le problème est ailleurs :

    Si je clique trop sur le bouton j'arrive à une saturation mémoire : je suppose que le système "créé" des bitmaps à chaque occurrence de "new" et que cela fini par faire "trop".


    J'ai voulu alors mettre la déclaration Mybitmap1 un fois pour toute en dur (en "général" en introduction des lignes de programmes avec les variables générales du programme) et utiliser quelque chose comme :
    (...)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mybitmap1.image= image.fromfile("c:\.............\image.jpg")
    mais cela ne résout pas le problème de mémoire : la déclaration newgraphic1 est elle elle aussi "récurrente" et saturant la mémoire ? Je ne pensais pas mais peut être... ?


    dernière idée qui m'est venu : sauvegarder mon image modifiée dans un fichier et la charger pour la voir.
    Le problème est que je ne epux le faire qu'une fois : à la seconde tentative il refuse de l'écraser.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Dim myBitmap1 As New Bitmap("C:\Users\Utilisateur...\image.JPG" 'Je crée un BitMap
    Dim newgraphic1 As Graphics = Graphics.FromImage(myBitmap1) 'je crée un Graphics à partir du BitMap
    newgraphic1.DrawEllipse(mypen, nux1 + l, nuy1 + l, rayon1, rayon1) ' je dessine sur mon Graphics
    mybitmap.save ("c:\........\imagetransitoire") 'sauvegarder mon image sur un fichier à part
    picturebox.image= image.fromfile("c:\........\imagetransitoire") 'je mets dans ma picturebox le fichier créé
    file.delete("c:\........\imagetransitoire") 'détruire le fichier image provisoire sur le disque
    newgrpahic1.dispose() ' je ferme le graphics
    mybitmap1.dispose() 'fermer ainsi toutes les ressources graphiques en cours
    cette manipulation ne marche pas : impossible d'effacer le fichier car "il est en cours d'utilisation" ...

    Je ne sais pas comment (et quand) fermer ce fichier.


    Comme vous le voyez, je me suis enfoncer bien loin dans des aspects complexes qui me dépassent surement : il doit certainement y avoir une méthode simple pour :

    - charger une image
    - la modifier et la laissée apparente
    - pouvoir recharger au même endroit le fichier original et refaire l'opération
    - sans saturer la mémoire.

    Je cherche depuis 3 jours sur le net, j'ai essayé de parcourir ce forum, mais je n'ai plus d'idées et viens vous demander un petit coup de main !

    je me décourage un peu, VB6 était plus souple pour les néophytes comme moi : VB.net semble nécessiter une plus grande compréhension de ses fondements profonds, si vous voyez ce que je veux dire !


    Mille mercis d'avance.

    William

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 200
    Par défaut
    pour tous les types simples codés en .net (le framework es en grande partie codé en .net) il y a un truc qui s'occupe de libérer la mémoire
    pour les choses qui viennent de dlls externes (les images sont gérées par gdi et gdi+, un peu comme sous vb6 d'ailleurs) il faut préciser explicitement quand on a plus besoin de la variable, via la méthode .Dispose qui libère la mémoire

    donc si tu créés des images à chaque fois en effet ca remplit la mémoire

    déjà pour commencer, le fait qu'appeler Dispose sur le bitmap efface le picturebox c'est normal, tu donnes une image au picturebox puis tu la détruit, donc il ne plus l'afficher

    après sur la libération de mémoire, avant de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    picturebox.image= mybitmap1
    il suffit d'ajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if picturebox.image isnot nothing then picturebox.image.Dispose
    en effet tu n'as plus besoin de l'ancienne image, et c'est elle qui reste en mémoire, donc tu peux la détruire avant de mettre la nouvelle


    concernant le fichier, .fromfile verrouille le fichier je crois

    et en effet .net nécessite de comprendre quelques concepts avant de commencer, comme les types par valeur et les types par référence :
    type par valeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    dim a as integer = 8
    dim b as integer = a
    ' a et b vallent 8
    b = 7
    'b vaut 7 mais a vaut toujours 8
    type par référence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    dim a as new bitmap(320,320)
    dim b as bitmap = a
    ' a et b pointent vers la même image
    b.Dispose
    'b est détruit (plus utilisable) mais a aussi
    les types par valeurs sont les types primitifs (boolean, integer, date, string ...) ainsi que les structures (qui existaient en vb6)
    la variable pointe vers un espace mémoire de la pile dans lequelle est stocké la valeur directement

    les types par référence ce sont toutes les classes (button, image, filestream ...)
    la variable pointe vers un espace mémoire dans la pile qui contient un pointeur vers un espace mémoire sur le tas
    ainsi quand on met une variable dans une autre, c'est le pointeur qui est recopié, il n'y a toujours qu'un espace mémoire qui contient l'objet
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre averti
    Homme Profil pro
    passionné
    Inscrit en
    Janvier 2016
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : passionné
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2016
    Messages : 22
    Par défaut
    Merci pour ces éléments.

    Je crois avoir compris et j'ai donc pu ajuster :
    j'ai créer dans la partie global mon Mybitmap
    Ensuite au déclenchement du bouton, je charge l'image dans ce mybimap (par valeur puisque je pointe vers un objet réel de mon disque)
    J'en crée un newgraphic1 sur lequel je dessine ! ce newgraphic1 pointe en fait vers l'objet "mybitmap" (par référence donc) qui est mis à jour
    je vérifie si la picturebox est vide (sinon je l'efface par dispose)
    je mets ma bitmap modifiée dans ma picturebox
    j'efface newgraphics1 qui n'est plus utile.


    Code VB.net : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    (...)
    Dim myBitmap1 As Bitmap
    (...)
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
     myBitmap1 = New Bitmap("C:\Users\.....")
    Dim newgraphic1 As Graphics = Graphics.FromImage(myBitmap1)
    newgraphic1.DrawLine(myPen, ivirtuel, j, ivirtuel + 1, j)
    If picturebox.Image IsNot Nothing Then picturebox.Image.Dispose()
    picturebox1.Image = myBitmap1
    newgraphic1.Dispose()
    End sub


    Dire que j'ai hésité à demander...

    Je te remercie sincèrement. cela marche parfaitement bien.

    Je remercie aussi les modérateurs qui ont pris la peine de corriger mon post pour le rendre plus lisible !
    j'ai essayé de suivre les conseils cette fois ci :-)


    EDIT : je sais pas pourquoi mon code sort en rouge ... Le forum analyse les erreurs ?

    j'espère que cela n'est pas génant ni une "faute".

    ReEDIT = j'ai corrigé !


  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 200
    Par défaut
    quelques détails et un peu de terminologie :

    Citation Envoyé par william44af Voir le message
    j'ai créer dans la partie global mon Mybitmap
    c'est une variable de classe (un form est une classe aussi)
    au passage on réserve le dim pour l'utilisation dans un membre (= sub function ou property)
    pour une variable de classe (ou les membres) on préfère préfixer par la portée
    private = visible dans la classe seulement
    public = visible partout
    friend = visible dans l'exe ou la dll seulement
    protected = private + visibilité par héritage (il faut voir la POO pour ça, et y a protected friend aussi mais plus rarement utile)
    donc plutot
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private myBitmap1 As Bitmap

    Citation Envoyé par william44af Voir le message
    Ensuite au déclenchement du bouton
    sur l'évènement click du bouton

    Citation Envoyé par william44af Voir le message
    je charge l'image dans ce mybimap (par valeur puisque je pointe vers un objet réel de mon disque)
    image.Fromfile créé une instance de la classe image, en lisant les octets sur le disque dur image est un objet au sens programmation, un fichier sur le disque ce n'est qu'un fichier sur le disque

    Citation Envoyé par william44af Voir le message
    J'en crée un newgraphic1 sur lequel je dessine ! ce newgraphic1 pointe en fait vers l'objet "mybitmap" (par référence donc) qui est mis à jour
    la classe graphics permet le dessin sur un "device" qui peut être un écran, une image ou une imprimante
    le graphics ne pointe pas vers le bitmap, on peut lui spécifier un bitmap sur lequel dessiner, qu'il garde en référence dans une variable de classe (au final on doit quand même pouvoir dire qu'il pointe sur le bitmap )

    Citation Envoyé par william44af Voir le message
    je vérifie si la picturebox est vide
    plutot si la propriété image (qui pointe vers une variable de classe aussi) contient une référence vers un objet de type image
    car tant qu'il n'y a pas d'image, il y a Nothing, qui veut dire pointeur null

    Citation Envoyé par william44af Voir le message
    sinon je l'efface par dispose
    Dispose fait que la mémoire externe à .net est libérée, mais l'instance de la classe bitmap existe toujours, y compris en mémoire dans .net
    dans les faits ca efface l'image de l'écran, car le picturebox quand il voudra se dessiner verra qu'il a bien quelque chose dans sa propriété Image, mais quand il voudra y accéder il se prendra une erreur (objet disposé plus utilisable) et ne dessinera donc rien
    ici vu qu'on remet quelque chose tout de suite ca ne pose pas de soucis, mais sinon il faudrait aussi écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    picturebox1.image = Nothing

    y a encore plein de choses sympathiques sur .net à connaitre, qui permettent de diminuer fortement le nombre de lignes de code (entre 5 et 20x moins que pour la même chose en vb6), comme la POO, LINQ, la reflection, les attributs, les threads etc...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

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

Discussions similaires

  1. Client travaillant sur une image
    Par Amnael dans le forum Réseau
    Réponses: 4
    Dernier message: 10/11/2015, 11h14
  2. [Débutant] Travailler sur une liste d'images
    Par medsyorick dans le forum Images
    Réponses: 1
    Dernier message: 17/07/2013, 17h13
  3. Réponses: 6
    Dernier message: 15/11/2007, 12h31
  4. Réponses: 1
    Dernier message: 06/07/2006, 12h11
  5. Comment mettre un label sur une image
    Par dug dans le forum MFC
    Réponses: 3
    Dernier message: 07/04/2004, 10h40

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