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

Delphi Discussion :

Travailler sur une image à partir du Device Context


Sujet :

Delphi

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Travailler sur une image à partir du Device Context
    Bonjour,

    Je suis débutant en delphi et je souhaite travailler avec une dll sur une image affichée à l'ecran dont je ne connais que le Device context.

    Ci dessous mon code qui ne fonctionne pas:

    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
    25
    26
    27
    library Ma;
     
    uses
      SysUtils,Controls,Windows,Graphics,ExtCtrls,
      Classes;
     
    {$R *.res}
     
      function NbPoint(n : integer):integer; stdcall;
      var DC : HDC;
      Image: TImage;
     
      begin
     
      Image := Timage.Create(Self);
      DC := getdc(n);
      Image.Canvas.Handle := DC;
      Result := Image.Width;
      ReleaseDC(n,DC)
     
      end;
     
    exports
            NbPoint;
     
    begin
    end.
    Y a t-il quelqu'un pour me le corriger ?

    Merçi

  2. #2
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    D'abord, petite remarque concernant les règles d'utilisation du forum :
    (je l'ai rajouté pour toi)

    Après cette parenthèse, voici une réponse :
    La première chose, c'est que lorsque tu crées un objet (quel qu'il soit) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Image := Timage.Create(Self);
    Il faut penser à le détruire quelque part (sinon il reste en mémoire et windows fini par ne pas être content du tout !).
    Juste avant le End de ton "device Context" par exemple, c'est bien.
    De plus, quand tu libères un objet graphique, le "Device Context" que tu lui as assigné est lui aussi libéré, donc tu n'as plus besoin du release :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     function NbPoint(n : integer):integer; stdcall;
    var DC : HDC;
    Image: TImage;
     
    begin
     
    Image := Timage.Create(Self);
    DC := getdc(n);
    Image.Canvas.Handle := DC;
    Result := Image.Width;
    Image.Free; //<-- Libération de l'objet créé
    end;



    Le premier problème provient du fait que tu utilises un TImage.
    A la place, il faudrait que tu utilises un TBitmap (et encore...).

    TImage, ne représente en RIEN une image, c'est un composant visuel qui peut contenir une image. Bref, en résumé, un TImage n'est pas une image.
    C'est bien pour afficher une image sur une fiche, mais pas terrible pour travailler sur une image !

    Par contre un TBitmap (Le TImage contient un TBitmap), oui, ça représente une image que l'on peut manipuler.

    Donc, pour l'instant, voici ton nouveau code :
    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
    25
    library Ma;
     
    uses
    SysUtils,Controls,Windows,Graphics,ExtCtrls,
    Classes;
     
    {$R *.res}
     
    function NbPoint(n : integer):integer; stdcall;
    var DC : HDC;
    Image: TBitmap;
     
    begin
      Image := TBitmap.Create;
      DC := getdc(n);
      Image .Canvas.Handle := DC;
      Result := Image.Width;
      Image.Free;
    end;
     
    exports
    NbPoint;
     
    begin
    end.
    Mais ce n'est pas fini !
    Comme tu l'as remarqué, le Handle du "Device Context", en delphi, est toujours une propriété de TCanvas. C'est normal, un "Device Context" ne te donnes pas accès à une image bitmap, mais à une "surface de dessin".
    Ainsi, pour dessiner sur une Image (un TBitmap), on passe par sa "surface de dessin" (représentée par TCanvas).
    Mais il n'y a pas que les Images qui proposent une surface de dessin, une fenètre (TForm) en propose une, un TPanel en propose une aussi, ainsi que TButton, TMemo, le bureau et l'écran (accessibles via la variable Screen), l'imprimante (printer), etc...
    Donc, quand tu accèdes à un objet Windows via son "Device Context", tu accèdes en fait à sa "surface de dessin", tu es donc en présence, ni plus ni moins, d'un TCanvas, mais pas forcément d'une image.

    Ce que tu dois retenir
    "Device Context" (Windows) est équivalent à "TCanvas" (Delphi)
    Donc on va remplacer TBitmap par TCanvas...
    Mais en faisant ceci, il ne faut pas oublier que TCanvas ne libère pas le "Device Context" qu'on lui assigne (comme le faisait TBitmap ou TImage), on a donc le retour de Release...
    De là ton nouveau code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function NbPoint(n : integer):integer; stdcall;
    var DC : HDC;
    Image: TCanvas;
    begin
      Image := TCanvas.Create;
      DC := getdc(n);
      Image.Handle := DC;
      Result := Image.Width; //<--là, ça va coincer...
      Image.Free;
      ReleaseDC(n,DC); //<--on l'a remis...
    end;
    Là, tu es coincé... : Un TCanvas ça n'a ni largeur ni hauteur ! ça s'étend de "moins l'infini" à "plus l'infini" (en théorie) aussi bien en X qu'en Y.

    Celà te permet de dessiner en dehors de la vue (pour dessiner une portion de cercle sur le bord d'une fiche ou d'une image par exemple).
    Mais, TCanvas possède une propriété ClipRect, qui représente les limites du rectangles où le dessin peut s'effectuer. Par defaut, si cette valeur n'a pas été modifiée pour restreindre la zone où le dessin peut s'effectuer, elle contient implicitement la hauteur et la largeur de ton "image", voici ton nouveau code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function NbPoint(n : integer):integer; stdcall;
    var DC : HDC;
    Image: TCanvas;
    Largeur:integer;
    begin
      Image := TCanvas.Create;
      DC := getdc(n);
      Image.Handle := DC;
      Largeur:=Image.ClipRect.Right-Image.ClipRect.Left;
      Result := Largeur;
      Image.Free;
       ReleaseDC(n,DC);
    end;
    Mais ce n'est pas fini ! Il y a encore un problème avec
    - ça :
    NbPoint(n : integer)
    - ça :
    DC := getdc(n);
    - et ça :
    Citation Envoyé par CMOINI
    ...dont je ne connais que le Device context.
    Bref, dans ta fonction NBPoint, si j'ai bien compris, tu passes en paramètre un "Device Context" :
    - tu as déjà un Device Context, pas la peine d'en demander un à windows.
    - corriges ta déclaration de fonction (on va y revenir dans le nouveau code)
    - si tu vas voir dans l'aide "SDK Windows", tu verras que GetDC attend un HWnd (c'est un handle de fenètre, par un "Device Condext" : même si l'un et l'autre sont des entiers, ce n'est pas pareil).
    Un handle de fenètre c'est l'ID (un identifiant unique) d'une fenètre (TForm en Delphi), du bureau (égale à zéro), d'un contrôle fenètré (TPanel par exemple et tout les descendants de TWinControl)

    Rappel : une fenètre (ou un contrôle fenétré), est un objet qui peut lui même contenir des fenètres (ou des contrôles fenétrés), ainsi que des contrôles qui eux, ne sont pas fenétrés (TGaphicControl).

    Donc, il ne faut pas confondre Form1.Handle (HWNd) et Canvas.Handle (HDC)...

    Pour un même Handle de fenètre (HWnd) tu peux obtenir de windows autant de "Device Context" (HDC) que tu veux ! (mais faut pas en abuser ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DC_Fiche1:=GetDC(Form1.Handle);
    DC_Fiche2:=GetDC(Form1.Handle);
    ...
    Et puis du coup, on a plus besoin du Release...

    Bref, voici ton nouveau code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function NbPoint(DC : HDC):integer; stdcall;
    var Image: TCanvas;
    Largeur:integer;
    begin
      Image := TCanvas.Create;
      Image.Handle := DC;
      Largeur:=Image.ClipRect.Right-Image.ClipRect.Left;
      Result := Largeur;
      Image.Free;
    end;
    Bon, voilà, maintenant, ça devrait marcher

    Sinon, en se passant de TCanvas, on peut réaliser la même fonction avec les API Windows en se passant d'un TCanvas (puisque un "HDC" est fait pour ça...) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    function NbPoint(DC : HDC):integer; stdcall;
    var ARect:TRect;
    begin
      GetClipBox(DC, ARect);
      Largeur:=ARect.Right-ARect.Left;
      Result := Largeur;
    end;
    Bon dev
    Bidouilleuse Delphi

Discussions similaires

  1. [Débutant] Travailler sur une liste d'images
    Par medsyorick dans le forum Images
    Réponses: 1
    Dernier message: 17/07/2013, 17h13
  2. ranger des images sur une feuille à partir d'un classeur
    Par bobafric dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 27/08/2010, 09h25
  3. Réponses: 4
    Dernier message: 26/03/2008, 09h10
  4. Une infobulle à partir des coordonnées sur une image
    Par dark_vidor dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 28/01/2006, 21h20

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