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

Lazarus Pascal Discussion :

Un Bitmap rempli par code ne s'affiche pas sur TImage mais s'écrit bien dans un fichier


Sujet :

Lazarus Pascal

  1. #1
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut Un Bitmap rempli par code ne s'affiche pas sur TImage mais s'écrit bien dans un fichier
    Yes, it's me again, avec encore un truc de malade, mais alors comme ça, je n'avais jamais vu...

    Dans un programme trouvé chez efg, il est question de remplir un TBitmap (qui a comme petit nom BitmapHS, "HS" parce que "HSV", chez efg on fait dans le trifouillage de couleurs) avec des données, puis de le faire afficher dans un TImage.

    Rien d'anormal et j'en vois certains qui se demandent qu'est-ce que j'ai bien encore pu prendre ce midi...
    Attendez, ne partez pas, c'est là que ça devient rigolo : entre l'appel à la fonction (à qui on passe les paramètres qui vont bien) et l'instruction suivante qui consiste à afficher les données, si j'insère un BitmapHS.SaveToFile('bmptest.BMP'); , hé bien, selon certains paramètres (que je maîtrise, genre PixelFormat à 24 ou 32 bits, déclarés bien en amont) le fichier contient un magnifique cercle coloré :
    Nom : test.jpg
Affichages : 602
Taille : 10,6 Ko
    (oui oui, ce fichier a été créé par code, sinus, cosinus, scanline, toussa toussa...)

    La question c'est : pourquoi je n'ai rien dans mon TImage ? Des fois j'ai une image blanche, des fois noire, des fois grise en fonction de certains paramètres, mais ce rainbow circle, makkache bono...

    J'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ImageHS.Canvas.Draw(0, 0, BitmapHS); // original
    ImageHS.Picture.Assign(BitmapHS);
    ImageHS.Picture.Graphic := BitmapHS; 
    BitmapHS.Canvas.StretchDraw(rect, ImageHS.Picture.Graphic );
    et je n'ai jamais vu ce cercle qui est présent dans le BitmapHS.

    Je récapitule : dans une proc j'appelle une fonction en lui passant des paramètres.
    Au retour (si j'ai bien choisi ma configuration) je crée un fichier impeccable à partir du bitmap et ensuite je le fais afficher dans le Timage.
    Sauf que l'affichage est à la rue...
    Et àmha ça ne peut pas être un problème dans le bitmap puisque le fichier est bon...

    Une dernière info à tomber par terre : dans le zip il y avait un .exe créé avec D3 (200 ko, une misère, une honte, même ), qui... fonctionne parfaitement sous XP
    À ceux qui supposeraient que je me suis foutu dedans avec mon scanline, je rappelle que le scanline a généré la magnifique image 10 lignes plus haut !

    Si quelqu'un a une idée, ou veut des précisions, qu'il n'hésite pas car là, je suis sec, moi...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 852
    Points : 11 285
    Points
    11 285
    Billets dans le blog
    6
    Par défaut
    Et que donne un ImageHS.Picture.LoadFromFile('bmptest.BMP'); ?

    Ecrire sur le Canvas du TImage n'est pas censé fonctionner en dehors de son OnPaint :
    Citation Envoyé par freepascal.org
    Note : À l'intérieur de Image1.OnPaint Image1.Canvas pointe vers l'aire visible volatile. En dehors de Image1.OnPaint l'Image1.Canvas pointe vers Image1.Picture.Bitmap.Canvas.
    J'aurais parié sur ImageHS.Picture.Assign(BitmapHS); Il faudrait que je passe aux tests.
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut
    Bonsoir, Yves,

    et bravo !
    Citation Envoyé par tourlourou Voir le message
    Et que donne un ImageHS.Picture.LoadFromFile('bmptest.BMP'); ?
    D'après toi ?
    Ben une très jolie image de cercle arc-en-ciel, lol !

    Citation Envoyé par tourlourou Voir le message
    J'aurais parié sur ImageHS.Picture.Assign(BitmapHS); Il faudrait que je passe aux tests.
    Qu'est-ce que tu veux dire par "J'aurais parié sur... " ? Que cette instruction était la solution ?

    Citation Envoyé par tourlourou Voir le message
    En fait, ce qui m'a mis sur la piste c'est ce qui précède, "n'est pas censé fonctionner en dehors de... " J'ai suivi le lien, j'y ai d'abord trouvé
    Note : À l'intérieur de Image1.OnPaint Image1.Canvas pointe vers l'aire visible volatile. En dehors de Image1.OnPaint [ce qui est mon cas] l'Image1.Canvas pointe vers Image1.Picture.Bitmap.Canvas.
    mais je n'ai pas été fichu d'utiliser Image1.Picture.Bitmap.Canvas ; par contre, en remontant un peu sur la page, j'ai retrouvé quelque chose que j'avais déjà utilisé il y a longtemps sans noter en gros en gras et au fer rouge cette histoire de peinture en dehors du OnPaint, bref, en remontant un peu sur la page, disais-je, j'ai (re-)trouvé ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        BitmapHS.SaveToStream(memstream);
        memstream.Position:=0;
        ImageHS.Picture.Bitmap.LoadFromStream(memstream);
    Et voilà

    On peut continuer à discuter, mais d'ores et déjà je peux cocher ,

    PS :qui a dit que l'informatique c'était simple ?
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    Février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : Février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Si je peux me permettre de petites précisions sur le Canvas, Bitmap... d'un TImage :

    Un TImage utilise en interne un bitmap qui lui sert de "mémorisation" de ce qu'il doit afficher sur son propre Canvas.

    Lorsqu'on assigne une image à la propriété Picture, ce bitmap est automatiquement créé si l'on utilise une des 3 méthodes :
    • Evidemment, en assignant dans l'EDI
    • Image1.Picture.Loadfromfile('fichier.bmp')
    • Image1.Picture.Assign(monbitmap)


    Si on n'assigne pas d'image à la propriété Picture, le bitmap interne est automatiquement créé dès que l'on dessine sur le Canvas du TImage. (Image1.Canvas.Ellipse...). Le bitmap est créé à la taille actuelle du TIMage.

    Si on n'assigne pas d'image à la propriété Picture, le code suivant ne peut pas marcher :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Image1.Picture.Bitmap.Canvas.Draw(0,0,bmp);
    Et pour cause, car Picture ne contient pas encore de bitmap.

    Par contre, ceci marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Image1.Canvas.Draw(0,0,bmp);
    L'utilisation du Canvas de TImage entraine création du bitmap interne. Si mes souvenirs sont bons, lorsque le Canvas de TImage est modifié, il y a appel à la fonction PictureChanged (qui actualise le bitmap).

    On peut donc aussi dessiner sur le Canvas de l'image et ce dessin sera repris lors du SaveToFile de TPicture.Graphic
    Mais ceci n'est valable que si on est en dehors de l'événement OnPaint du TImage. Tout ce qui est dessiné dans cet événement n'affecte pas le bitmap interne ! On parle "d'aire volatile".

    Cordialement
    Thierry

    PS: Veuillez excuser mon ton peut-être un peu professoral.

    EDIT : voir post de correction

  5. #5
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut
    Citation Envoyé par ThWilliam Voir le message
    Si je peux me permettre de petites précisions sur le Canvas, Bitmap... d'un TImage :
    You're welcome !

    Citation Envoyé par ThWilliam Voir le message
    Par contre, ceci marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Image1.Canvas.Draw(0,0,bmp);
    L'utilisation du Canvas de TImage entraine création du bitmap interne. Si mes souvenirs sont bons, lorsque le Canvas de TImage est modifié, il y a appel à la fonction PictureChanged (qui actualise le bitmap).
    Et pourtant...
    Comme dit dans le post d'origine, c'est bien l'instruction que j'ai trouvée dans le code d'efg, et heureusement qu'il y avait aussi l'exe dans le zip, pour constater que son outil fonctionne encore sous XP et sous Seven ! Redoutables, ces exe's compilés avec D3
    En fait, je pense à des histoires de cross-compilations chatouilleuses, avec des implémentations parfois un poil différentes au niveau du code machine. C'est possible, ça ?

    Citation Envoyé par ThWilliam Voir le message
    PS: Veuillez excuser mon ton peut-être un peu professoral.
    C'est toujours un plaisir de lire des posts bien écrits et qui expliquent bien les choses ; tu reviens quand tu veux avec "ton ton professoral", moi ça m'va
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  6. #6
    Responsable Lazarus & Pascal

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    Février 2013
    Messages
    1 436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 1 436
    Points : 20 855
    Points
    20 855
    Billets dans le blog
    84
    Par défaut
    Citation Envoyé par ThWilliam Voir le message
    Lorsqu'on assigne une image à la propriété Picture, ce bitmap est automatiquement créé si l'on utilise une des 3 méthodes :
    • Evidemment, en assignant dans l'EDI
    • Image1.Picture.Loadfromfile('fichier.bmp')
    • Image1.Picture.Assign(monbitmap)
    Bravo pour l'explication très claire et largement juste. Cependant, le mécanisme est un peu plus subtil : il suffit de donner une dimension au bitmap pour qu'il soit parfaitement exploitable. [Il se peut que le bitmap soit bien créé par défaut (sinon une exception serait déclenchée lorsqu'on tenterait de dessiner dedans), mais qu'il ait des dimensions nulles. Point à vérifier...]

    Nom : 2016-05-18_170025.png
Affichages : 455
Taille : 45,7 Ko

    Ainsi, on place deux images sur une fiche :

    • la première, initialisée depuis l'EDI par une image au choix, servira de source du bitmap ;
    • la seconde est vierge.


    On ajoute trois boutons :

    • le premier tente d'exécuter le code fautif qui consiste à dessiner dans un bitmap aux dimensions nulles : rien ne s'affichera [situation déjà décrite] ;
    • le second initialise les dimensions du bitmap aux valeurs voulues et le bitmap apparaît [pas besoin d'utiliser une des trois méthodes directement] ;
    • le troisième fixe les dimensions à 0 et le bitmap disparaît...


    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    type
     
      { TForm1 }
     
      TForm1 = class(TForm)
        btnSimpleDraw: TButton;
        btnWithSize: TButton;
        btnClear: TButton;
        imgTo: TImage;
        imgFrom: TImage;
        procedure btnSimpleDrawClick(Sender: TObject);
        procedure btnWithSizeClick(Sender: TObject);
        procedure btnClearClick(Sender: TObject);
      private
        { private declarations }
      public
        { public declarations }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.lfm}
     
    { TForm1 }
     
    procedure TForm1.btnSimpleDrawClick(Sender: TObject);
    // *** ne fonctionne pas => TPicture vide ! ***
    begin
      imgTo.Picture.Bitmap.Canvas.Draw(0,0,imgFrom.Picture.Bitmap);
    end;
     
    procedure TForm1.btnWithSizeClick(Sender: TObject);
    // *** OK : TPicture dimensionné avant le dessin ***
    begin
      imgTo.Picture.Bitmap.SetSize(imgFrom.Width, imgFrom.Height);
      imgTo.Picture.Bitmap.Canvas.Draw(0,0,imgFrom.Picture.Bitmap);
    end;
     
    procedure TForm1.btnClearClick(Sender: TObject);
    // *** taille nulle => pas de dessin ! ***
    begin
      imgTo.Picture.Bitmap.SetSize(0,0);
    end;


    Citation Envoyé par ThWilliam Voir le message
    PS: Veuillez excuser mon ton peut-être un peu professoral.
    Ce n'est pas encore une insulte
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

  7. #7
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut
    Citation Envoyé par gvasseur58 Voir le message
    Bravo pour l'explication très claire et largement juste. Cependant, le mécanisme est un peu plus subtil : il suffit de donner une dimension au bitmap pour qu'il soit parfaitement exploitable. [Il se peut que le bitmap soit bien créé par défaut (sinon une exception serait déclenchée lorsqu'on tenterait de dessiner dedans), mais qu'il ait des dimensions nulles. Point à vérifier...]
    C'est bien, on fait des révisions avec TP, c'est toujours utile, je trouve

    J'ai vérifié le point dont tu parles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      with imgTo.Picture.Bitmap do
        ShowMessage(IntToStr(Width) + '--' + IntToStr(Height)); // -->  0--0
    end;
    et pas de message d'erreur.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  8. #8
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    Février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : Février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Bravo pour l'explication très claire et largement juste. Cependant, le mécanisme est un peu plus subtil : il suffit de donner une dimension au bitmap pour qu'il soit parfaitement exploitable. [Il se peut que le bitmap soit bien créé par défaut (sinon une exception serait déclenchée lorsqu'on tenterait de dessiner dedans), mais qu'il ait des dimensions nulles. Point à vérifier...)
    J'ai de fait manqué de précision. Merci de le faire remarquer.

    Après consultation de customimage.inc :

    1) le TPicture est de fait créé dans le constructeur.
    2) Quand on n'assigne pas d'image à TPicture : un bitmap aux dimensions du TImage est assigné à Picture.Graphic à la première utilisation de Image.Canvas (propriété qui fait appel à la fonction GetCanvas).

    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
    function TCustomImage.GetCanvas: TCanvas;
    var
      TempBitmap: TBitmap;
    begin
      //debugln('TCustomImage.GetCanvas A ',DbgSName(Self),' ',DbgSName(FPicture.Graphic));
      if not FUseAncestorCanvas and (FPicture.Graphic = nil) then
      begin
        // make a new bitmap to draw on
        TempBitmap := TBitmap.Create;
        try
          TempBitmap.Width := Width;
          TempBitmap.Height := Height;
          FPicture.Graphic := TempBitmap;
        finally
          TempBitmap.Free;
        end;
      end;
      //debugln(['TCustomImage.GetCanvas B ',DbgSName(Self),' ',DbgSName(FPicture.Graphic),' FUseParentCanvas=',FUseAncestorCanvas]);
      // try draw on the bitmap, not on the form's canvas
      if not FUseAncestorCanvas and (FPicture.Graphic is TBitmap) then
        Result := TBitmap(FPicture.Graphic).Canvas
      else
        Result := inherited Canvas;
    end;
    Cordialement
    Thierry

  9. #9
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut
    Bonjour,

    je reviens sur ça, parce qu'après vous avoir lu, et après avoir fait des manips, je voudrais partager avec vous le résultat d'un petit test -- le partager parce que tout seul, c'est vraiment trop lourd à porter.
    Qu'on en juge :
    dans une procédure quelconque de la fiche principale d'un petit programme, il y a l'appel à une fonction qui va construire toute une image dans un bitmap qu'elle va se créer, donc en gros ça ressemble à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    VAR
      BitmapHS     :  TBitmap;
    BEGIN
      BitmapHS := la_fonction(param1, param2, etc);
    Ensuite, le but de la manip c'est de faire afficher à l'utilisateur les résultats de cette construction, et donc, après l'appel de la fonction, tout ce que je m'amuse à faire c'est de commenter / décommenter des lignes dans le bout de code qui suit de manière à n'avoir qu'une seule fonctionnalité à la fois, et je vous laisse lire les commentaires rajoutés à la suite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ImageHS.Canvas.Draw(0, 0, BitmapHS); // --> image toute noire
     
    ImageHS.Picture.Graphic := BitmapHS; // --> image vide
     
    BitmapHS.SaveToStream(memstream);
    memstream.Position:=0;
    ImageHS.Picture.Bitmap.LoadFromStream(memstream); // --> cercle coloré
    Et moi je me demande (et je vais peut-être dire une énorme bêtise, mais pour l'instant je n'ai pas d'autre explication) si ces 3 résultats vraiment différents alors qu'ils ne devraient pas, si j'ai bien compris le film, ne seraient pas liés au fait qu'au lieu de trafiquer le bitmap dans la procédure, tout se joue dans une fonction planquée dans un module à grands coups de RESULT.paramètres, RESULT représentant bien entendu le bitmap.

    Si jamais tout le monde répond "oui bien sûr c'est ça", attention, je rétorque aussitôt que l'exe fourni pour Windows fonctionne très bien sous Windows ! (maintenant, il y a peut-être un écart de code entre le fichier source et le fichier binaire ?)
    Voilà voilà voilà...


    Et quand on aura trouvé la solution à cette douloureuse question, je vous parlerai du pourquoi du comment en fonction des paramètres passés j'ai le cercle coloré ou (ou exclusif !) d'autres graphiques qui s'affichent : vous verrez, c'est pas triste non plus parce que, que les graphiques calculés foirent en fonction des paramètres passés, je veux bien l'admettre, mais que ça fasse disparaître le cercle coloré où ils n'interviennent pas, là j'ai du mal...
    En résumé j'ai soit image noire, soit image vide, soit graphiques, soit cercle coloré quand je devrais avoir graphiques sur cercle coloré !

    Et les graphiques, puisqu'on en parle, c'est juste le dessin d'un cercle gris concentrique au coloré avec un rayon variable, et le dessin du rayon au max : pas de quoi fouetter un chat...
    Nom : cercletgraphics.png
Affichages : 438
Taille : 22,1 Ko Bon, l'image est toute moche (réduction de taille à l'arrache), mais vous voyez le principe.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  10. #10
    Responsable Lazarus & Pascal

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    Février 2013
    Messages
    1 436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 1 436
    Points : 20 855
    Points
    20 855
    Billets dans le blog
    84
    Par défaut
    Citation Envoyé par Jipété Voir le message
    dans une procédure quelconque de la fiche principale d'un petit programme, il y a l'appel à une fonction qui va construire toute une image dans un bitmap qu'elle va se créer, donc en gros ça ressemble à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    VAR
      BitmapHS     :  TBitmap;
    BEGIN
      BitmapHS := la_fonction(param1, param2, etc);
    Je pressens que le problème est justement dans cette fonction "quelconque". Elle peut construire toutes les images qu'elle veut, il est indispensable de créer un buffer sur lequel on dessine AVANT de le transférer sur le canevas de la fenêtre. Pire : les lignes que tu produis montrent que tu mélanges les canevas sans vergogne .

    Les résultats que tu obtiens ne sont pas vraiment surprenants : soit tu exploites un bitmap vide (dimensions nulles), soit tu affectes à une zone volatile, soit tu obtiens ce qui est recherché, car tu te sers de la zone qui contient vraiment le bitmap du cercle coloré.

    Il faut se souvenir qu'il y a DEUX zones dans une TImage (contrairement à une TPaintbox qui n'a qu'un canevas volatile).

    Il y a tout d'abord le TCanvas qui contient l'image volatile visible et redessinée à chaque appel de l'événement OnPaint. C'est celui auquel tu accèdes par exemple dans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    BitmapHS.SaveToStream(memstream);
    Il y a ensuite TImage.Picture.Bitmap.Canvas qui contient l'image persistante. Ce canevas est indépendant de l'image affichée (qui peut être tronquée, étirée...). C'est ce que tu utilises ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    ImageHS.Picture.Bitmap.LoadFromStream(memstream);
    On se rend parfaitement compte de l'existence des deux canevas quand une image est tronquée parce que trop grande pour la zone d'affichage. Un coup de Stretched := True, et hop l'image est ajustée Mais pour être ajustée, il fallait bien qu'elle fût () stockée quelque part, non ?

    En gros, si l'on mélange les canevas volatiles et persistants, on croit obtenir des aberrations

    Pour résumer :
    TImage.Canvas = pointe vers la zone d'affichage volatile dans OnPaint et enclenche le dessin vers l'autre bitmap en dehors de ce gestionnaire d'événement ;
    TImage.Picture.Bitmap.Canvas = canevas persistant, stocke l'image réelle sur laquelle on travaille.
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

  11. #11
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut
    Merci pour tes explications.

    Je relève ça, quand même :
    Citation Envoyé par gvasseur58 Voir le message
    Je pressens que le problème est justement dans cette fonction "quelconque". Elle peut construire toutes les images qu'elle veut, il est indispensable de créer un buffer sur lequel on dessine AVANT de le transférer sur le canevas de la fenêtre. Pire : les lignes que tu produis montrent que tu mélanges les canevas sans vergogne .
    car je n'ai rien écrit de tout ce fourbi, j'essaye juste de l'adapter...

    Voici donc une copie d'écran de la procédure absolument pas retouchée (quand je récupère des trucs, je me crée un dossier "source" et cette image a été prise depuis le .pas original :
    Nom : proc_hsv.png
Affichages : 520
Taille : 19,2 Ko

    Là on est dans le .pas principal, il n'y a que 3 lignes car tout le boulot est fait par la fonction CreateHueSaturationCircle(params...) planquée dans un autre module.

    Mais les grands esprits se rencontrent : Je pressens que le problème est justement dans cette fonction "quelconque". Lis la suite, écrite il y a dix minutes :

    il est pas d'heure et ça faisait deux ou trois jours que j'étais là-dessus (bon, pas à plein temps non plus, mais pas loin), je suis vanné mais j'ai gagné : je ne sais pas si c'est Lazarus ou FreePascal qui met sa pagaille, mais malheureusement j'avais raison : le bitmap n'est pas (ou mal) renvoyé par la fonction
    C'est fou, non ?

    Car le code de la fonction, rapatrié dans une procédure en y remplaçant seulement RESULT par BitmapHS fait que ça fonctionne et que l'objet Timage reçoit bien (enfin, à condition d'utiliser la combine du Tmemorystream) les données à afficher. Grande victoire ! :
    Nom : rainbowcircle.png
Affichages : 566
Taille : 23,3 Ko

    Le seul souci qui me reste, c'est que le jaune est à 9 h quand il devrait être entre 1 et 2 h, et quand il sera là le rouge devra être à 3 h : je suis encore un peu loin du compte, de ce côté-là, mais au moins je vois quelque chose !

    Deux bouts de code avec les commentaires qui vont bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //  BitmapHS.PixelFormat := pf24bit; // extérieur du cercle est noir :-(
      BitmapHS.PixelFormat := pf32bit;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        // Fill with background color
        BitmapHS.Canvas.Brush.Color := BackGroundColor;
    //  BitmapHS.Canvas.FillRect(BitmapHS.Canvas.ClipRect); // à commenter sinon image pas visible, même dans la procédure...
    Alors, oui, je tire à boulets rouges sur nos outils, mais j'ai écrit ça après avoir dépatouillé mes misères et avant de lire ton post, et je rappelle que l'exe fourni dans le zip fonctionne...
    Je ne sais pas si j'aurai le courage de redémarrer mon vieux portable w95 avec D3 pour aller vérifier de quoi il retourne.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  12. #12
    Responsable Lazarus & Pascal

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    Février 2013
    Messages
    1 436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 1 436
    Points : 20 855
    Points
    20 855
    Billets dans le blog
    84
    Par défaut
    Bonjour Jipété,

    Tu es courageux et opiniâtre , et tes expériences font qu'on apprend, révise et par conséquent progresse : alors, continue .

    Citation Envoyé par Jipété Voir le message
    malheureusement j'avais raison : le bitmap n'est pas (ou mal) renvoyé par la fonction
    C'est fou, non ?
    C'est fou, mais peut-être un peu faux aussi . Il est trop tôt pour je teste, mais il reste le problème de l'affectation sans préparation du résultat de ta fonction à un Bitmap non créé (et ça me gêne un peu).
    Ce qui me renforce dans mon inquiétude, c'est ce que tu écris ensuite :

    Citation Envoyé par Jipété Voir le message
    Car le code de la fonction, rapatrié dans une procédure en y remplaçant seulement RESULT par BitmapHS fait que ça fonctionne
    Il se pourrait bien que ta fonction initialise en interne correctement le Bitmap. A vérifier (promis, je vais garder un peu de temps dans la journée pour me pencher sur le problème).

    En revanche, je te rejoins entièrement quand tu soupçonnes Free Pascal / Lazarus de ne pas être tout à fait des clones de Delphi : l'implémentation des outils graphiques n'est forcément pas la même (questions de copyright et de portabilité) et ça se sent dans les programmes qui sortent des affichages triviaux. Ainsi, inutile de dépoussiérer un vieux PC : le programme d'origine (j'ai toujours admiré le site efg) est compilable en l'état par la version d'évaluation de Delphi Berlin .
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

  13. #13
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut
    Bonjour Gilles,

    et merci pour tes compliments, ils me vont droit au cœur et me font chaud à l'âme
    Citation Envoyé par gvasseur58 Voir le message
    Tu es courageux et opiniâtre , et tes expériences font qu'on apprend, révise et par conséquent progresse : alors, continue .
    Citation Envoyé par gvasseur58 Voir le message
    C'est fou, mais peut-être un peu faux aussi . Il est trop tôt pour je teste, mais il reste le problème de l'affectation sans préparation du résultat de ta fonction à un Bitmap non créé (et ça me gêne un peu).
    J'ai une piste : lors de la conversion du projet Delphi en projet Lazarus, j'ai oublié l'arrivée de {$MODE Delphi} en tête des unités, ligne qui n'existe pas quand je fais Projet / Nouveau projet... C'est ce truc qui m'a rendu fou, copier/coller un même code d'un projet à un autre et avoir un rendu différent , et m'y a fait passer un temps considérable, d'autant plus que dans l'unité principale du projet converti j'ai remplacé cette directive par {$mode objfpc}{$H+}, remplacement non fait dans les autres unités...
    Et comme l'une de ces unités embarque la fonction de dessin du cercle, ceci explique peut-être (sans doute ?) cela.
    Pas le temps de le confirmer par d'autres tests.
    Enfin bon, je vois le bout du tunnel.

    Alors pour vous remercier de votre patience à tous, et du temps que certains ont passé avec moi, d'abord une jolie image (réduite de moitié) :
    Nom : maquette.jpg
Affichages : 466
Taille : 31,3 Ko On comparera avec le cercle de l'exe original : Nom : cercletgraphics.png
Affichages : 421
Taille : 22,1 Ko -- Vue, la différence de position du rouge (et des autres) par rapport au jaune ? J'ai encore du pain sur la planche...

    Ensuite, en pseudo code les points les plus intéressants ; les commentaires en anglais sont d'origine -- noter le jonglage entre for i... for j et for j... for i avec l'imbrication des row[i] row [j] : une poule n'y retrouverait pas ses poussins, surtout avec les boutons 3 et 4 :
    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
    28
    29
    30
    31
    32
    // bouton 1 WH:
      FOR i := 0 TO BitmapHS.Width-1 DO BEGIN
        FOR j := 0 TO BitmapHS.Height-1 DO BEGIN
          row := pRGBQuad(Scanline);
          WITH row[i] DO
     
    // bouton 2 HW:
      FOR j := 0 TO BitmapHS.Height-1 DO BEGIN
        FOR i := 0 TO BitmapHS.Width-1 DO BEGIN
          row := pRGBQuad(Scanline);
          WITH row[j] DO
     
    // bouton 3 WH:
      FOR i := 0 TO BitmapHS.Width-1 DO BEGIN
        FOR j := 0 TO BitmapHS.Height-1 DO BEGIN
          row := pRGBQuad(BitmapHS.Scanline[Image3.Width - 1 - i]);// [] va de 199 à 0
          WITH row[j] DO
     
    // bouton 4 HW:
      FOR j := 0 TO BitmapHS.Height-1 DO BEGIN
        FOR i := 0 TO BitmapHS.Width-1 DO BEGIN
          row := pRGBQuad(BitmapHS.Scanline[Image4.Width - 1 - j]);// [] va de 199 à 0
          WITH row[i] DO
     
    // bouton 5 (appel fonction) :
              // Shift 90 degrees so H=0 (red) occurs along "X" axis
    //          H := H + 90; // le jaune est à 9 h, pas bon
              H := H + 210; 
     
    // FormActivate (tout dans la procédure) :
              // Shift 90 degrees so H=0 (red) occurs along "X" axis
              H := H + 90; // le jaune est à 9 h, pas bon
    Et enfin, pour les plus courageux et/ou curieux, le zip qui permet de jouer avec cette maquette (que j'ai testé avant de le mettre en téléchargement) :
    testscanline.zip
    ch'suis pas là c't'aprème.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  14. #14
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    bonjour,

    il faudrait voir s'il n'est pas possible d'utiliser le Cercle d'Andres pour faire ça
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  15. #15
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut
    Yop !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 1re étape : l'effet miroir
    //      row := RESULT.Scanline[Size - 1 - j]; // original -- Scanline[Size - 1 - j] va de 199 à 0
          // jaune à 9 h, orange puis rouge en descendant, vert puis cyan en montant
          row := RESULT.Scanline[j]; // [j] va de 0 à 199
          // jaune à 9 h, orange puis rouge en montant, vert puis cyan en descendant
          // --> ligne Scanline[j] = miroir vertical de Scanline[Size - 1 - j]
     
    // 2e étape : la rotation
              // Shift 90 degrees so H=0 (red) occurs along "X" axis
              // H=0 indique le rouge, présenté à 3 h
              // et le trait noir indique la couleur choisie (passée en paramètre)
              // Tourne dans le sens inverse des aiguilles d'une montre, méfiance !
    //          H := H + 90; // le jaune est à 9 h
              H := H + 330 ;
    Nom : le_but.png
Affichages : 423
Taille : 25,1 Ko

    Ce que j'ai un peu de mal à comprendre, c'est que cette variable, H, est utilisée pour positionner le trait noir indiquant la couleur choisie (dans l'interface du gros projet), mais qu'elle intervient également dans le positionnement du cercle coloré.

    Il doit rester une blagounette cachée dans un coin, qui échappe à mon œil de lynx !

    Et en parlant de mystère, que dans le gros projet toutes les unités soient en mode Delphi ou en mode objfpc ne change rien au rendu des images dans l'interface


    Citation Envoyé par Paul TOTH Voir le message
    bonjour,

    il faudrait voir s'il n'est pas possible d'utiliser le Cercle d'Andres pour faire ça
    Paul, merci pour ce lien que je ne connaissais pas du tout, je teste ça ASAP
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  16. #16
    Responsable Lazarus & Pascal

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    Février 2013
    Messages
    1 436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 1 436
    Points : 20 855
    Points
    20 855
    Billets dans le blog
    84
    Par défaut
    Bonsoir,

    Citation Envoyé par Jipété Voir le message
    Ce que j'ai un peu de mal à comprendre, c'est que cette variable, H, est utilisée pour positionner le trait noir indiquant la couleur choisie (dans l'interface du gros projet), mais qu'elle intervient également dans le positionnement du cercle coloré.
    Je ne suis pas sûr de comprendre ton problème (), mais que H (pour Hue = la teinte) intervienne dans le positionnement initial du cercle des couleurs est normal si l'on considère que l'emplacement de ces couleurs est normalisé :

    • 0° ou 360° : rouge ;
    • 60° : jaune ;
    • 120° : vert ;
    • 180° : cyan ;
    • 240° : bleu ;
    • 300° : magenta.

    Cependant, il y a plusieurs variables H locales à des procédures : dans UpdateHSVRectangles, TrackBarHSVChange, TrackBarRGBChange, sans compter les fonctions de l'unité HSVLibrary. Ce ne sont évidemment pas les mêmes "H".


    Citation Envoyé par Jipété Voir le message
    Et en parlant de mystère, que dans le gros projet toutes les unités soient en mode Delphi ou en mode objfpc ne change rien au rendu des images dans l'interface
    Je n'avais pas répondu à cette voie qui avait toutes les (mal)chances d'être une impasse : le mode Delphi intervient dans la syntaxe et dans quelques fonctionnalités du langage, mais (à ma connaissance) pas dans l'implémentation des bibliothèques, y compris graphiques.
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

  17. #17
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Citation Envoyé par Paul TOTH Voir le message
    bonjour,

    il faudrait voir s'il n'est pas possible d'utiliser le Cercle d'Andres pour faire ça
    Paul, merci pour ce lien que je ne connaissais pas du tout, je teste ça ASAP
    Voilà, j'ai testé pour vous, je ne suis pas sûr qu'en l'état, ça apporte grand chose 1. Je suis parti du lien, j'ai trouvé en bas de page du code MicroLua très facilement adaptable, je ne pense pas m'être gourré puisque je suis très vite arrivé à ça :
    Nom : Andres_circle.png
Affichages : 437
Taille : 1,4 Ko

    On notera que je retombe sur mes vieux démons :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    //    Image5.Picture.Graphic := ecran; // rien d'affiché -- OK avec les lignes dessous...
        memstream := TMemoryStream.create;
        ecran.SaveToStream(memstream);
        memstream.Position:=0;
        Image5.Picture.Bitmap.LoadFromStream(memstream);
    ("ecran" c'est le nom du TBitmap, explications dans le code et/ou le lien) C'est gonflant, à la longue.

    Je joins le fichier si certains veulent tester : une fiche avec dessus un TButton et un TImage et c'est tout : andrescircle.pas
    ---
    1 : j'ai mis au début du .pas un lien vers des infos sur MicroLua où j'y ai même trouvé une fonction nommée MakeGradient.
    C'est peut-être à ça que pensait Paul, faudrait juste aller fouiller dans SourceForge et essayer de récupérer le code pour le réécrire en Pascal, mais, au final, est-ce qu'au fin fond du bout du code, quand on est tout près de la machine et que notre beau listing a été transformé en hexadécimal illisible par un compilateur efficace, est-ce que le fait d'utiliser un MakeGradient sera vraiment différent de l'utilisation de ScanLine et de pRGBQuad quand, au final, il s'agit juste d'écrire en mémoire des informations qui seront interprétées de la même façon par la carte graphique : tel pixel a telle couleur, tel autre a telle autre, etc., ou plutôt, telle adresse mémoire a telle donnée, telle autre a telle autre, etc., tout ça à coups de PUSH et autres instructions machine ?
    Faudrait faire des tests pointus de performances...
    À ce propos, quelqu'un a déjà testé la directive {inline on} associée à des procédure tagguées inline; ? Merci pour tout retour là-dessus.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  18. #18
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut
    Bonsoir, Gilles,

    croisement de réponses
    Citation Envoyé par gvasseur58 Voir le message
    Je ne suis pas sûr de comprendre ton problème (), mais que H (pour Hue = la teinte) intervienne dans le positionnement initial du cercle des couleurs est normal si l'on considère que l'emplacement de ces couleurs est normalisé :
    Oui, je me suis peut-être mal exprimé... À force, je finis par ne plus du tout savoir où j'en suis.
    J'y réfléchirai à tête reposée...

    Citation Envoyé par gvasseur58 Voir le message
    Je n'avais pas répondu à cette voie qui avait toutes les (mal)chances d'être une impasse : le mode Delphi intervient dans la syntaxe et dans quelques fonctionnalités du langage, mais (à ma connaissance) pas dans l'implémentation des bibliothèques, y compris graphiques.
    Bon, ben merci pour cette certitude.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  19. #19
    Responsable Lazarus & Pascal

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    Février 2013
    Messages
    1 436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 1 436
    Points : 20 855
    Points
    20 855
    Billets dans le blog
    84
    Par défaut
    Citation Envoyé par Jipété Voir le message
    On notera que je retombe sur mes vieux démons :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    //    Image5.Picture.Graphic := ecran; // rien d'affiché -- OK avec les lignes dessous...
        memstream := TMemoryStream.create;
        ecran.SaveToStream(memstream);
        memstream.Position:=0;
        Image5.Picture.Bitmap.LoadFromStream(memstream);
    Oui, il s'agit bien de démons , mais sans doute dus à la fatigue. Toutes ces lignes peuvent être remplacées par une seule :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Image5.Canvas.Draw(0,0, ecran);
    Ainsi, tu recopies ce que tu as dessiné sur ton canevas de travail (ecran) sur le canevas d'affichage (Image5.Canvas) alors que Image5.Picture.Graphic est celui de stockage...

    Si tu veux écrire dans le canevas de stockage puis l'afficher, tu dois forcer l'affichage avec Repaint :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Image5.Picture.Graphic := ecran;
    Image5.Repaint;
    Tu verras, ça marche

    Citation Envoyé par Jipété Voir le message
    Bon, ben merci pour cette certitude.
    Ce n'est pas une certitude : j'ai bien écrit que c'était "à ma connaissance" .
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

  20. #20
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 718
    Points : 15 097
    Points
    15 097
    Par défaut
    Citation Envoyé par gvasseur58 Voir le message
    Oui, il s'agit bien de démons , mais sans doute dus à la fatigue. Toutes ces lignes peuvent être remplacées par une seule :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Image5.Canvas.Draw(0,0, ecran);
    Ainsi, tu recopies ce que tu as dessiné sur ton canevas de travail (ecran) sur le canevas d'affichage (Image5.Canvas) alors que Image5.Picture.Graphic est celui de stockage...

    Si tu veux écrire dans le canevas de stockage puis l'afficher, tu dois forcer l'affichage avec Repaint :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Image5.Picture.Graphic := ecran;
    Image5.Repaint;
    Tu verras, ça marche .
    ou, au choix ou les deux,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //    Image5.Picture.Graphic := ecran; // rien d'affiché -- OK avec les lignes dessous...
    //    Image5.Repaint; // avec ça rajouté sur les conseils de Gilles, AV !
        memstream := TMemoryStream.create;
        ecran.SaveToStream(memstream);
        memstream.Position:=0;
        Image5.Picture.Bitmap.LoadFromStream(memstream);
    //AV    Image5.Canvas.Draw(0,0, ecran);
    Et sois tranquille que je fais bien attention : soit juste les lignes 1 et 2, soit la 7 toute seule, soit les 3 à 6.

    Et regarde ce que j'ai découvert, tout à l'heure :
    dans le code d'origine d'efg, il a fallu que je commente une ligne, sinon image vide, pas affichée, j'en sais rien mais en tout cas je ne vois rien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      // Fill with background color
      BitmapHS.Canvas.Brush.Color := BackgroundColor;
      //BitmapHS.Canvas.FillRect(BitmapHS.Canvas.ClipRect); // empêche l'affichage
    Hé bien dans le code du bouton 6 pour tester le cercle de Paul, regarde bien (et tous ces boutons sont construits de la même manière, dans la même unité) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      // Fill with background color
      ecran.Canvas.Brush.Color := clGreen;//clBtnFace;
      ecran.Canvas.FillRect(ecran.Canvas.ClipRect); // empêche l'affichage, sauf ici !


    Citation Envoyé par gvasseur58 Voir le message
    Ce n'est pas une certitude : j'ai bien écrit que c'était "à ma connaissance" .
    En tout cas, de ce que j'en ai vu, le programme se comporte de la même manière quel que soit le mode sélectionné.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

Discussions similaires

  1. [Débutant] Exécuter une requete par code et l'afficher
    Par adelcrb dans le forum C#
    Réponses: 14
    Dernier message: 12/09/2013, 13h58
  2. Accéder aux colonnes d'un GridView rempli par code
    Par lamouche42 dans le forum ASP.NET
    Réponses: 4
    Dernier message: 29/04/2013, 12h10
  3. Pourquoi ce code ne m'affiche pas la bonne valeur ?
    Par Mr. X dans le forum Débuter
    Réponses: 20
    Dernier message: 19/09/2008, 09h48
  4. GUI Java par netbeans - ne s'affiche pas
    Par G_angel dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 31/01/2007, 11h38
  5. <li> ne s'affiche pas sur IE mais s'affiche sur FF
    Par pierrot10 dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 05/12/2006, 16h06

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