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 :

Scanline et D7 : problème avec l'exemple de l'aide


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 132
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut Scanline et D7 : problème avec l'exemple de l'aide
    Bonsoir à toutes et à tous.

    Ayant décidé d'étudier Scanline, j'ai utilisé l'ami F1 dans mon D7 et suis tombé sur un exemple sympathique (à première vue) que je me suis empressé de copier/coller. Voici la chose :
    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
    procedure TForm1.Button1Click(Sender: TObject);
    // Cet exemple montre le dessin direct dans le BitMap
    var
      x,y : Integer;
      BitMap : TBitMap;
      P : PByteArray;
    begin
      BitMap := TBitMap.create;
      try
        // Sous Windows remplacer MyBitmap.png par un nom de chemin complet tel que
        // C:\Program Files\Common Files\Borland Shared\Images\Splash\256color\factory.bmp
        BitMap.LoadFromFile('MyBitmap.png');
        for y := 0 to BitMap.Height -1 do
        begin
          P := BitMap.ScanLine[y];
          for x := 0 to BitMap.Width -1 do
            P[x] := y;
        end;
        Canvas.Draw(0,0,BitMap);
      finally
        BitMap.Free;
      end;
    end;
    Le problème (constaté avec plusieurs images qui s'ouvrent parfaitement bien avec PSP, MSPaint et/ou Photoshop), vous le voyez sur l'image ci-dessous à gauche, le tiers gauche est un dégradé de gris...
    Je dis "le tiers" car j'ai mesuré, c'est bien le tiers : par exemple, l'image originale fait 189 pixels de large, la zone grise 63. Pareil avec d'autres images.

    Par ailleurs, quand on voit le commentaire Borland dans l'exemple, on se dit que ça fonctionnerait mieux avec des images en 256 couleurs, non ? Hé ben, laisse tomber, j'ai essayé avec leur "factory.bmp", résultat c'est complètement n'importe quoi dans ce cas, voir à droite.
    Voilà...
    Oui, j'ai lu le tuto de Nono mais pour bien le comprendre il me faut connaître les bases, et les bases c'est l'aide de Delphi, et sur ce coup-là, sale temps !

    Y aura-t-il un(e) spécialiste du graphisme pour m'éclairer ?

    Merci,
    --
    jp
    Images attachées Images attachées  

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut
    Yep,
    J'ai un peu creusé (« Aide-toi et le Ciel t'aidera » ) et suis en mesure d'apporter la précision suivante :
    « ils » racontent n'importe quoi dans l'aide puisque cet exemple n'utilise pas le résultat de la fonction Scanline (la PByteArrray), la preuve c'est qu'en virant la boucle « For », l'image chargée s'affiche parfaitement (on s'en serait douté), qu'elle soit en 8 ou en 24 bits.

    La bonne question, maintenant, est : pourquoi le traitement dans cette boucle met-il la panique, alors qu'il n'est pas utilisé ? Y a-t'il un rapport entre la PByteArray et le BitMap (indépendamment du fait qu'il y a sûrement une ByteArray dans chaque bitmap) ?
    Mais la déclaration des variables ne montre pas de lien entre P et BitMap...
    Et même s'il y en a un caché, pourquoi le fait de simplement lire me trafique les données de l'image ? Je suis perdu, là...

    Si quelqu'un pouvait m'expliquer en deux mots, ça serait cool.
    Merci,
    --
    jp

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 931
    Billets dans le blog
    6
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    P := BitMap.ScanLine[y];
    stocke l'adresse de la yème ligne de l'image dans P (balayage vertical)
    affecte la yème couleur de la palette ou la couleur y au xème pixel de la ligne

    pour une image codée en pf24bits (couleurs réelles sur 3 octets), on aurait déclaré P: ^array of TRGBTriple (ou qqch comme ça !)
    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 !

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut
    Ah, on se retrouve,
    P := BitMap.ScanLine[y]; stocke l'adresse de la yème ligne de l'image dans P (balayage vertical)
    D'accord, mais quel rapport entre ce P et le BitMap dans lequel l'image est chargée ?
    P[x] := y; affecte la yème couleur de la palette ou la couleur y au xème pixel de la ligne
    De quelle ligne ? Quel rapport, quel lien entre une PByteArray et un bitmap ?
    Si j'avais vu un truc style BitMap.PByteArray (ça veut rien dire mais c'est l'idée) j'aurais compris, mais là ?
    C'est comme si on me disait x := 5; et que ça modifie y.
    Comprends rien à c'truc, moi...
    --
    jp

  5. #5
    Membre Expert
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 704
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 704
    Par défaut
    Citation Envoyé par Jipété Voir le message
    D'accord, mais quel rapport entre ce P et le BitMap dans lequel l'image est chargée ?
    Le rapport est là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    P := BitMap.ScanLine[y];
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. :bug: ___ "http://club.developpez.com/regles/#LIII-A"Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.3 Entreprise - Visual studio 2022
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.7)

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut
    Bonjour Lung,

    Et merci de ta réponse, mais je la trouve plus que « light » et sybilline (ou alors ch'suis vraiment un boulet). En tout cas, désolé mais je n'ai toujours pas compris, et je ne vois toujours pas le lien...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    P := Bitmap.Scanline[y]
    Bien. Je traduis ça comme ça, moi :
    La propriété Scanline (en lecture seule !) du Bitmap va analyser la ligne [y] de l'image et retourner son résultat dans la PByteArray P.
    D'accord ?
    (Aide Delphi :
    ScanLine, propriété (TBitmap) : Offre un accès indicé à chaque ligne de pixels.
    )
    Comment/pourquoi la modification de cette PByteArray me modifie-t-elle l'image d'origine ?
    C'est un peu comme si on avait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var
      hauteur : integer;
    begin
      hauteur := BitMap.Height;
    et que du coup la Height du Bitmap soit modifiée.
    Vous voyez ma perplexité ?

    --
    jp

  7. #7
    Membre Expert
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 704
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 704
    Par défaut
    L'aide dit que ça renvoi un pointeur :
    property ScanLine[Row: Integer]: Pointer;
    Donc, pour moi : est la même chose que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    BitMap.ScanLine[y][x] := y;
    Je me trompe ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. :bug: ___ "http://club.developpez.com/regles/#LIII-A"Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.3 Entreprise - Visual studio 2022
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.7)

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut
    Je me trompe ?
    Je ne sais, Lung, je ne sais pas (et c'est pour ça que je poste, note bien ! )
    Je viens de faire la chose suivante :
    1. « Nouvelle application », juste une form et un bouton ;
    2. Appeler l'aide Delphi de Scanline ;
    3. Copier/coller l'exemple dans l'évènement du bouton et adapter le chemin ;
    4. À l'exécution je gagne l'image ci-dessous.

    Peut-être que c'est ça que Borland veut montrer ? Auquel cas je trouve leur commentaire (Cet exemple montre le dessin direct dans le BitMap) plus qu'inadapté et n'expliquant rien du tout...
    Pas vous ?
    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
    procedure TForm1.Button1Click(Sender: TObject);
    // Cet exemple montre le dessin direct dans le BitMap
    var
      x,y : Integer;
      BitMap : TBitMap;
      P : PByteArray;
    begin
      BitMap := TBitMap.create;
      try
        // Sous Windows remplacer MyBitmap.png par un nom de chemin complet tel que
        // C:\Program Files\Common Files\Borland Shared\Images\Splash\256color\factory.bmp
    // Donc :
    //    BitMap.LoadFromFile('MyBitmap.png');
    // Et :
        BitMap.LoadFromFile
          ('C:\Program Files\Fichiers communs\Borland Shared\Images\Splash\256Color\factory.bmp');
        for y := 0 to BitMap.Height -1 do
        begin
          P := BitMap.ScanLine[y];
          for x := 0 to BitMap.Width -1 do
            P[x] := y;
        end;
        Canvas.Draw(0,0,BitMap);
      finally
        BitMap.Free;
      end;
    end;
    --
    jp de + en + perplexe...
    Images attachées Images attachées  

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut
    Cherchez plus j'ai trouvé !

    L'explication vient de chez efg (avec un bout de chez Michel Bardou), dans un exemple de random :
    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
      VAR
       Bitmap:  TBitmap;
       i     :  INTEGER;
       j     :  INTEGER;
       Row   :  pByteArray;
    begin
    ...
        FOR j := 0 TO Bitmap.Height-1 DO
        BEGIN
          // MB : Scanline est un pointeur sans type vers un tableau des lignes du bitmap
          Row := pByteArray(Bitmap.Scanline[j]);
          FOR i := 0 TO (Bitmap.Width DIV PixelsPerByte)-1  DO // PixelsPerByte = 8
          BEGIN
            Row[i] := Random(256)
          END
        END;
    L'exemple de l'aide n'est donc pas terrible terrible (pour rester poli) !
    Bah, il m'aura au moins servi à chercher pour comprendre, et c'est toujours ça de gagné,
    --
    jp

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

Discussions similaires

  1. [2.x] Problème avec l'exemple de base
    Par Henry22 dans le forum Symfony
    Réponses: 3
    Dernier message: 10/04/2015, 13h26
  2. Problème avec un exemple PC_Soft - Champ Upload
    Par Jimmy666 dans le forum WebDev
    Réponses: 2
    Dernier message: 15/11/2012, 14h23
  3. Ogre-CEGUI : problème avec les exemples
    Par coda_blank dans le forum Ogre
    Réponses: 1
    Dernier message: 19/11/2010, 19h54
  4. Réponses: 2
    Dernier message: 30/05/2007, 13h11
  5. [FOP] Problème avec les exemples fournis
    Par Androrion dans le forum XML/XSL et SOAP
    Réponses: 10
    Dernier message: 22/08/2006, 14h54

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