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 :

Comparer deux fichiers Bitmap [Lazarus]


Sujet :

Lazarus Pascal

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 131
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 131
    Par défaut Comparer deux fichiers Bitmap
    Hello, it's me again -- désolé.

    Je ne voulais pas vous embêter si vite mais franchement, il y a des jours on se demande...

    Suite à mes récents déboires avec des images transparentes qui ne devraient pas l'être, je me suis mis en tête de bricoler vite fait un petit outil pour comparer des fichiers.
    En même temps je me proposais de tester l'astuce que m'a passée anapurna concernant Scanline, mais on verra ça après, parce que d'entrée ça part mal.

    Est-ce que vous voyez un défaut à cet algo (le premier fichier est parfaitement bien chargé par ailleurs, ça, ça concerne le second fichier et la comparaison) ?
    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
    procedure TForm1.Button2Click(Sender: TObject);
    var
      pic: TPicture;
      p1,p2: pRGBQuad;
      h,w: integer;
    begin
      if not opd.Execute then exit;
      pic := TPicture.Create;
      try
        pic.LoadFromFile(opd.Filename); // chargement du fichier
        imgDisplay.Picture.Bitmap.BeginUpdate;
        // parcours vertical
    //    for h := 0 to imgDisplay.Picture.Bitmap.Canvas.Height-1 do begin
    //    for h := 0 to imgDisplay.Picture.Bitmap.Height-1 do begin
        for h := 0 to imgDisplay.Height-1 do begin
    //      p1 := pRGBQuad(imgDisplay.Picture.Bitmap.ScanLine[h]);
    //      p2 := pRGBQuad(pic.Bitmap.Scanline[h]);
    // dessus en attente que ça fonctionne dessous
          p1 := pRGBQuad(imgDisplay.Picture.Bitmap.RawImage.GetLineStart(h));;// source
          p2 := pRGBQuad(pic.Bitmap.RawImage.GetLineStart(h));// second fichier
          // parcours horizontal
    //      for w := 0 to imgDisplay.Picture.Bitmap.Canvas.Width-1 do begin
    //      for w := 0 to imgDisplay.Picture.Bitmap.Width-1 do begin
          for w := 0 to imgDisplay.Width-1 do begin
            if pRGBQuad(p1[w]) <> pRGBQuad(p2[w]) then begin // test et action si différence
              // 2 lignes pour voir la vie des choses
              memo1.Lines.Add(inttostr(h)+' '+inttostr(w));// de 299 303 à 299 399 -- le fic de test fait 400 x 300
              Application.ProcessMessages;
    // obligé de mettre ces 4 lignes en commentaire sinon SIGSEGV en fin de boucle
    {          p1[w].rgbBlue :=0;
              p1[w].rgbGreen:=0;
              p1[w].rgbRed  :=255;
              p1[w].rgbReserved:=255;   }
            end; // test
          end; // for w
        end; // for h
        imgDisplay.Picture.Bitmap.EndUpdate;
      finally
        pic.Free;
      end;
    end;
    Vous noterez que j'ai fait trois tentatives de balayage, avec toujours le même résultat, SIGSEGV

    Et maintenant le truc qui tue, indépendamment de l'AV en fin de boucle : pour tester, avant de m'embarquer avec des fichiers dont je ne sais pas où sont les différences et s'il y en a, je teste en ouvrant deux fois le même fichier, et j'ai des lignes logguées dans le mémo !

    Mais comment c'est possible un cauchemar pareil ?

    Ah, tiens, si quelqu'un veut essayer rapidement, un TOpenPictureDialog, un TImage alClient dans un TPanel avec Color à clWhite et ça roule :
    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.OpenImage(Filename: string);
    var
      pic: TPicture;
    begin
      pic := TPicture.Create;
      pic.Bitmap.Transparent:=False;
      try
        pic.LoadFromFile(Filename);
        if (pic.Width <> pnl4img.Width) or (pic.Height <> pnl4img.Height) then begin
          pnl4img.Width  := pic.Width;
          pnl4img.Height := pic.Height;
        end;
        imgDisplay.Picture.Assign(pic);
      finally
        pic.Free;
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if opd.Execute then OpenImage(opd.FileName);
      Button2.SetFocus;
    end;

  2. #2
    Membre Expert

    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
    Par défaut
    Salut JP.

    On peut dire que tu m'en fais faire des tests !

    Malheureusement pour toi, c'est sous Windows.

    J'ai repris ton code de comparaison de deux bitmaps avec le code de mise en rouge "décommenté".
    Ces bitmaps sont créés sous PShop, enregistrés en mode windows 32bits. Le deuxième a une toute petite différence avec le premier.
    Ils sont "loadés" en runtime.
    Résultat : Cela marche impec ! Seuls les pixels différents sont peints en rouge.

    Alors, où est ton erreur ? Je n'en sais rien.

    Bonne soirée.
    Thierry

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 131
    Par défaut
    Bonsoir Thierry,

    Citation Envoyé par ThWilliam Voir le message
    On peut dire que tu m'en fais faire des tests !


    Citation Envoyé par ThWilliam Voir le message
    Malheureusement pour toi, c'est sous Windows.
    J'oublie toujours de tester dans cet environnement : quand ce sur quoi je bosse part en live, je m'engraine dessus et zappe complètement l'autre environnement

    Citation Envoyé par ThWilliam Voir le message
    Résultat : Cela marche impec ! Seuls les pixels différents sont peints en rouge.

    Alors, où est ton erreur ? Je n'en sais rien.
    Tu m'achèves, là. Tu me rassures cependant sur le fait que ça fonctionne comme je l'espérais.

    Mais tu m'achèves d'autant plus qu'après avoir posté j'ai farfouillé dans des vieux codes à la recherche d'une idée, et suis retombé sur un truc inutile mais qui fonctionne, une copie 1/1 à base de scanline ; je le mets ici, des fois que quelqu'un veuille l'étudier, mais bon, y a qu'une ligne, hein !
    Mais j'ai trouvé que ça ressemblait à ce que j'ai posté cet aprème, alors voilà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      with dst do begin
        Width:=src.Width; Height:=src.Height; // copie 1/1 pour le moment
        try
          BeginUpdate();
          for h := 0 to src.Height-1 do begin
            ps := pRGBQuad(src.RawImage.GetLineStart(h)); // scanline source
            pd := pRGBQuad(dst.RawImage.GetLineStart(h)); // scanline dest.
            for w := 0 to src.Width-1 do pd[w] := ps[w]; // la copie pRGBQuad par pRGBQuad
          end;
        finally
          EndUpdate();
        end;
      end;
    Bon, ben je vais chercher, mais où ?

    EDIT :
    Citation Envoyé par ThWilliam Voir le message
    Ces bitmaps sont créés sous PShop, enregistrés en mode windows 32bits.
    D'accord, mais, en mode BMP ou JPG ?

    Parce que sans rien changer au code j'arrive à faire fonctionner la comparaison sur des .jpg mais c'est moche à cause des artefacts,
    Nom : compar_a_b.png
Affichages : 496
Taille : 9,4 Ko la 1re image a un A rouge (tiens, faudrait que je change la couleur de comparaison), la 2e a un B, au même endroit.

    Par contre, en mode BMP c'est le SIGSEGV, que j'utilise 2 fois le même fichier ou 2 fichiers différents.
    J'en ai maaaaaaaaaaaaaaaaaaarre de cette informatique de pieds nickelés .

  4. #4
    Membre Expert
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Billets dans le blog
    2
    Par défaut
    Salut je viens de tester avac laz1.8rc1 32bits j'obtiens ça
    Nom : 2017-06-04_231609.jpg
Affichages : 504
Taille : 17,0 Ko

    Tu es sous linux ? non ? car la definitions de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
         RGBQUAD = record
              rgbBlue : BYTE;
              rgbGreen : BYTE;
              rgbRed : BYTE;
              rgbReserved : BYTE;
           end;
         tagRGBQUAD = RGBQUAD;
         TRGBQUAD = RGBQUAD;
         PRGBQUAD = ^RGBQUAD;
    se trouve dans l'unité windows. Elle est déclaré ou sous Linux et comment ?

    car là tu fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     if pRGBQuad(p1[w]) <> pRGBQuad(p2[w]) then begin // test et action si différence
    P1 et P2 ne sont pas des tableaux (dans mon cas) dons normal que tu es un SIGSEGV
    Et de plus on ne peux pas comparer directement deux variable de type record A moins que les opérateurs soient surchargés. Il faut donc tester chaque membre 1 à 1.

    j'ai modifié comme ça :

    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
    47
    48
    procedure TForm1.Button2Click(Sender: TObject);
      function RGBQuadIsEqual(c1,c2:TRGBQuad):Boolean;
      begin
        Result:=False;
        if ((c1.rgbBlue = c2.rgbBlue) and (c1.rgbGreen = c2.rgbGreen) and (c1.rgbRed = c2.rgbRed) and (c1.rgbReserved = c2.rgbReserved)) then result:= true;
      end;
     
    var
      pic: TPicture;
      p1,p2: pRGBQuad;
      h,w: integer;
    begin
      if not opd.Execute then exit;
      pic := TPicture.Create;
      try
        pic.LoadFromFile(opd.Filename); // chargement du fichier
        imgDisplay.Picture.Bitmap.BeginUpdate;
        // parcours vertical
        memo1.Lines.Add(inttostr(imgDisplay.Picture.Bitmap.Width)+' '+inttostr(imgDisplay.Picture.Bitmap.Height));
       for h := 0 to imgDisplay.Picture.Bitmap.Height-1 do
        begin
     
    // dessus en attente que ça fonctionne dessous
          p1 := pRGBQuad(imgDisplay.Picture.Bitmap.RawImage.GetLineStart(h));// source
          p2 := pRGBQuad(pic.Bitmap.RawImage.GetLineStart(h));// second fichier
          // parcours horizontal
          for w := 0 to imgDisplay.Picture.Bitmap.Width-1 do
          begin
            if not(RGBQuadIsEqual(p1^,p2^)) then
            begin // test et action si différence
              // 2 lignes pour voir la vie des choses
              memo1.Lines.Add(inttostr(h)+' '+inttostr(w));// de 299 303 à 299 399 -- le fic de test fait 400 x 300
             // Application.ProcessMessages;
     
              p1^.rgbBlue :=0;
              p1^.rgbGreen:=0;
              p1^.rgbRed  :=255;
              p1^.rgbReserved:=255;
            end; // test
            inc(p1);
            inc(p2);
          end; // for w
        end; // for h
        imgDisplay.Picture.Bitmap.EndUpdate;
      finally
        pic.Free;
      end;
    end;
    et ça roule et ha oui faut faire attention que soient bien des images 32bits et de dimensions identiques, évidemment

    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 131
    Par défaut
    Yep !
    Citation Envoyé par BeanzMaster Voir le message
    Tu es sous linux ? Elle est déclarée où sous Linux et comment ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    uses
      LCLtype, // pour pRGBQuad
    Citation Envoyé par BeanzMaster Voir le message
    P1 et P2 ne sont pas des tableaux (dans mon cas) donc normal que tu aies un SIGSEGV
    Je n'ai pas de SIGSEGV avec les .jpg.

    Citation Envoyé par BeanzMaster Voir le message
    Et de plus on ne peut pas comparer directement deux variables de type record à moins que les opérateurs soient surchargés. Il faut donc tester chaque membre 1 à 1.

    - Thierry a dit que pour lui ça fonctionnait ;
    - as-tu vu mon code de copie ? for w := 0 to src.Width-1 do pd[w] := ps[w]; // la copie pRGBQuad par pRGBQuad Quelque part la comparaison c'est pareil, enfin, il me semble.

    'fin bon, j'ai testé ton code avec des .bmp 32 bits, je n'ai plus de SIGSEGV mais le machin ne compare rien ou plutôt, ne détecte aucune différence, or il y en a une, j'en suis sûr !

    Citation Envoyé par BeanzMaster Voir le message
    et ça roule et ha oui faut faire attention que soient bien des images 32bits et de dimensions identiques, évidemment
    Tu lis trop vite ! J'ai bien dit que le premier test je le faisais sur le même fichier (oui, de 32 bits) donc obligatoirement de la même taille (je suis neuneu, mais y a des limites, )

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 933
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 933
    Par défaut
    D'accord avec beanzmaster

    Citation Envoyé par BeanzMaster Voir le message
    P1 et P2 ne sont pas des tableaux (dans mon cas) dons normal que tu es un SIGSEGV
    Et en Delphi, ça ne compilerait même pas avec une erreur E2016.

    Citation Envoyé par BeanzMaster Voir le message
    Et de plus on ne peux pas comparer directement deux variable de type record
    C'est pour cela qu'il est obligé de transtyper. Après, le type utilisé (pRGBQuad) est parfaitement aléatoire et prête plus à confusion qu'autre chose, P1[w] (si tableau) étant un TRGBQuad (une valeur, une couleur) et non un pointeur.
    Ça entraînerait même des erreurs sporadiques en 64 bits puisque le dernier pixel/pointeur serait lu au-delà du bloc de données du bitmap. Mieux vaudrait transtyper en integer.

    Citation Envoyé par Jipété Voir le message
    - as-tu vu mon code de copie ? for w := 0 to src.Width-1 do pd[w] := ps[w]; // la copie pRGBQuad par pRGBQuad Quelque part la comparaison c'est pareil, enfin, il me semble.
    Pas pRGBQuad mais TRGBQuad comme dit précédemment.

    Il y a d'autres contraintes avec les record et la comparaison ne pourrait fonctionner qu'en étant sûr qu'ils ont été initialisés à zéro ou qu'il y ait un Dest^ := Source^ quelque part.

    S'ils sont unpacked, que contiennent les paddings ? => ils sont indéterminés.
    S'ils contiennent une chaînes, disons string[10], et qu'on ne remplit que deux caractères, que valent les huit autres ? => ils sont aussi indéterminés.

    Ça devient compliqué pour le compilateur

  7. #7
    Membre Expert
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Billets dans le blog
    2
    Par défaut
    Tu lis trop vite ! J'ai bien dit que le premier test je le faisais sur le même fichier (oui, de 32 bits) donc obligatoirement de la même taille (je suis neuneu, mais y a des limites, )
    Je dis ça car les jpeg sont des fichiers 24bits en général mais jamais 32bits.(Pas de prise en charge de la transparence dans ce format) Mais ça à l'air de fonctionner pareil, ici pourquoi (car les pixels dans le rawimage ont une taille de 4 bytes (32bits) car sinon faudrait utiliser un TRGBTrible et non TRGAQuad. Le mieux est de tester le pixelformat (enfin mieux vaut se fier au RawImage.Description.Depth) et dirigé vers la bonne fonction 24 ou 32bits. Apres le pourquoi du comment c'est dans la sauce interne de la gestion des bitmap de la LCL.

    Sinon avec ton code que j'ai modifié les JPG passent, et les fichiers 32bits BMP également sans soucis
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

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

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

    en fait, au départ je ne voulais pas fouiller le site et au-delà le web (l'idée ne m'était même pas venue à l'esprit), j'étais parti en me disant que ça serait bouclé en 5 minutes, comme pour la copie qui, soit dit en passant, fonctionne très bien à partir de pRGBQuad.
    Mais ça doit être un coup de bol, de hasard, si je comprends bien.
    Va falloir que je revoie tous mes codes à base de scanline ? Fouhhh, suis pas rendu...
    Et si la détection chez Thierry fonctionne bien, c'est aussi un coup de bol ? Thierry, revois tes codes !

    Bon, en attendant et pour pouvoir répondre à Andnotor, je suis allé fouiller dans mes vieilles docs, j'y ai retrouvé un tuto de nono40 qui est la traduction d'un truc énorme d'efg (28 pages !), et dedans il y avait un petit lien "exemple de comparaison de deux images", hé hé hé !

    J'avais la solution sous la main !
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    // For bitmaps of the same size, count the number of pixels that match
    // and the number that are different.
    PROCEDURE CompareBitmaps(CONST BitmapA, BitmapB:  TBitmap;
                             VAR Total, Match, Differ:  INTEGER);
      TYPE
        TRGBTripleArray =  ARRAY[WORD] OF TRGBTriple;
        pRGBTripleArray =  ^TRGBTripleArray;
      VAR
        i   :  INTEGER;
        j   :  INTEGER;
        rowA:  pRGBTripleArray;
        rowB:  pRGBTripleArray;
    BEGIN
      ASSERT( (BitmapA.width  = BitmapB.width) AND
              (BitmapA.height = BitmapB.height),  'Different sizes');
     
      // Force bitmaps to have the same pf24bit Pixelformat
      // (this may be undesirable, for example, for large pf1bit bitmaps)
      BitmapA.PixelFormat := pf24bit;
      BitmapB.PixelFormat := pf24bit;
     
      Total  := BitmapA.width * BitmapA.height;
      Match  := 0;
      Differ := 0;
     
      FOR j := 0 TO BitmapA.height-1 DO
      BEGIN
        rowA := BitmapA.Scanline[j];
        rowB := BitmapB.Scanline[j];
     
        FOR i := 0 TO BitmapA.width-1 DO
        BEGIN
     
    {$IFDEF DELPHI5}
    {$DEFINE SIMPLEWAY}
    {$ENDIF}
     
    {$IFDEF DELPHI6}      // should work in D6
    {$DEFINE SIMPLEWAY}
    {$ENDIF}
     
    {$IFDEF SIMPLEWAY}    // update this for D7 or later
          // new easy way for D5 or later (actually D4.02 and later)
          IF   rowA[i] = rowB[i]
          THEN INC(Match)
          ELSE INC(Differ)
    {$ELSE}              // D3 and D4 cannot use "simple" way
          // "bug" in earlier versions forces more code for test
          // chapeau sinon compilo pas content ! -- modif jpt
          IF   (rowA^[i].rgbtRed   = rowB^[i].rgbtRed)   AND
               (rowA^[i].rgbtGreen = rowB^[i].rgbtGreen) AND
               (rowA^[i].rgbtBlue  = rowB^[i].rgbtBlue)
          THEN INC(Match)
          ELSE begin INC(Differ);
          form1.memo1.Lines.Add(inttostr(j)+' '+inttostr(i)); // ajout jpt
          end;
    {$ENDIF}
        END
      END
    END {CompareBitmaps};
     
    procedure TForm1.Button3Click(Sender: TObject);
    // http://nono40.developpez.com/tutoriel/delphi/efg/scanline/fichiers/CompareTBitmaps.TXT
    VAR
      Bitmap1:  TBitmap;
      Bitmap2:  TBitmap;
      PixelsDiffer:  INTEGER;
      PixelsMatch :  INTEGER;
      PixelsTotal :  INTEGER;
    begin
      Bitmap1 := TBitmap.Create;
      Bitmap2 := TBitmap.Create;
      TRY
        Bitmap1.LoadFromFile('/_share_4_VM/Programmation/bart/img_4_tests/400x300x32_v3_96.bmp');
        Bitmap2.LoadFromFile('/_share_4_VM/Programmation/bart/img_4_tests/400x300x32_v3M_96.bmp');
     
        CompareBitmaps(Bitmap1, Bitmap2, PixelsTotal, PixelsMatch, PixelsDiffer);
     
        // Sample output:  Total=307200, Match=265, Differ=306935
        ShowMessage(Format('Total=%d, Match=%d, Differ=%d',
                           [PixelsTotal, PixelsMatch, PixelsDiffer]));
      FINALLY
        Bitmap1.Free;
        Bitmap2.Free
      END
    end;
    et juste comme ça, ça fonctionne (source originale : encore efg ! Quel homme !), le log dans le mémo montre bien les coordonnées modifiées entre les deux fichiers (une lettre rajoutée), plus qu'à l'adapter pour mettre ça en couleur.

    Juste un point de détail : le compilo n'apprécie pas du tout que je définisse SIMPLEWAY, il me crie fort dessus à la ligne 44, IF rowA[i] = rowB[i], avec le message Error: Operator is not overloaded: "TRGBTripleArray" = "TRGBTripleArray" . Bah, l'autre manière de faire fonctionne, alors bon,

  9. #9
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 933
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 933
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Juste un point de détail : le compilo n'apprécie pas du tout que je définisse SIMPLEWAY, il me crie fort dessus à la ligne 44, IF rowA[i] = rowB[i], avec le message Error: Operator is not overloaded
    C'est ce que te disait BeanzMaster : tu ne peux pas directement comparer deux record sans définir un operator d'équivalence.

    Et ce n'est pas un détail, c'est exactement ce que tu faisais au départ qui ne fonctionne pas. Y a-t-il eu un essai de comparaison de record il y a... 17 ans (octobre 2000) ? Peut être, mais ça n'a manifestement pas fait long feu

    Citation Envoyé par Jipété Voir le message
    comme pour la copie qui, soit dit en passant, fonctionne très bien à partir de pRGBQuad.
    Oui mais non. pd est un pointeur, pd[w] est une valeur. pd[w] := ps[w], ce n'est pas une copie de pointeur mais de valeur, soit un TRGBQuad.
    L'activation de la syntaxe étendue fait que tu peux simplifier l'écriture. Ce qui se passe derrière est effectivement pd^[w] := ps^[w].

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 131
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    [...] Ce qui se passe derrière est effectivement pd^[w] := ps^[w].
    Ah ouais, mais alors, s'il se passe des trucs dans mon dos je n'y arriverai pas...

    Surtout si en plus personne ne percute sur les trucs que je considère les plus importants :
    • cité vers 15 h : il faut que j'active RGBTriple pour comparer des fichiers 32 bits ! Ça ne choque personne ? Genre il faut que je loue un bus de 24 places pour trimbaler 32 gamins au parc.
    • découvert ensuite : ai fouillé le web de fond en comble ("freepascal compare bitmap", il y a plein de réponses avec Delphi et quasiment rien avec FP [comm' d'hab' quoi]), ai vu plein de codes + ou - similaires, il n'y a rien qui fonctionne : soit ça ne trouve aucune différence, soit ça trouve tous les pixels en différence, avec des codes basés sur pByte, sur CompareMem, etc.

    Exemples :
    http://embarcadero.newsgroups.archiv...202254871.html
    http://delphidabbler.com/tips/145

    Y a des jours j'ai vraiment l'impression que mon carrosse a perdu une roue et qu'en plus il est tiré par un cheval boiteux...

    Pi là,
    Citation Envoyé par Andnotor Voir le message
    [...] Ce qui se passe derrière est effectivement pd^[w] := ps^[w].
    il faudrait m'expliquer plus en détail parce que dans mon code de copie, si je tape ce qui se passe derrière avec les petits chapeaux, je gagne
    Citation Envoyé par compilo_sans_humour
    Error: No default property available
    Fatal: Syntax error, ";" expected but "[" found
    avec le curseur qui clignote entre le 1er petit chapeau et le 1er crochet ouvrant.

    Citation Envoyé par Andnotor Voir le message
    [...] L'activation de la syntaxe étendue fait que tu peux simplifier l'écriture.
    Ça se cache où, le réglage de cette engeance ?

    Bon, j'ai encore la comparaison avec les streams à tester, et l'utilisation de PIntegerArray (en gros je pars dans tous les sens parce que le truc basique qui aurait dû être torché en 5 minutes m'a pété entre les mains, comme un artificier novice...)

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

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

    vous avez vu ? J'ai coché , et on n'y a passé que 8 jours !

    Nom : final.png
Affichages : 249
Taille : 198,7 Ko

    Pour réaliser cette magnifique image, voici donc un paquet-cadeau testé sous Linux 32bits et XP sp2, avec deux vieilles versions du couple FPC/Laz, ça compile et ça fonctionne : [EDIT] fichier_supprimé_par_moi
    Le fichier posté hier a été remplacé (détails dans le post suivant) par celui-ci : comparimgs2.zip
    [/EDIT]

    Le zip est un peu gros, c'est parce qu'il embarque les fichiers image que j'ai utilisés. Et vous pourrez lui faire "Clic droit / Extraire ici" car j'ai prévu un dossier parent qui enveloppe tout.

    Quelques détails et précisions :
    00- Oublié de dire que la chose ne gère que les .bmp et les .jpg, ça se voit vite en examinant le code mais ça ne coûte pas plus cher de prévenir avant,

    0- Oui, il y a une case à cocher "1 fic" pour zapper toute la partie "ouverture du second ficher et comparaison des datas", ça permet de vérifier viteuf' qu'un fichier s'ouvre bien.

    1- La chose a été vérifiée concernant les fuites mémoire : tout est bon.

    2- Structure des noms de fichiers-image :
    Code text : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    largeur x hauteur x pixelformat    = original sans modif
    largeur x hauteur x pixelformat_M  = original modifié
    largeur x hauteur x pixelformat_A  = original avec canal alpha (32 bits)
    largeur x hauteur x pixelformat_AA = original avec canal alpha (32 bits) et valeur modifiée, à voir avec un éditeur hexa (derniers pixels, les autres sont introuvables)
    largeur x hauteur x pixelformat_T  = pour jouer avec la checkbox "Transparence"
    3- Si vous voulez d'autres images pour tester, il existe ce site : https://testimages.org/

    4- Structure de l'unité unit1 :
    • au début les machins relatifs à la fiche : Create, Destroy, WindowStateChange et Resize
    • au milieu le cœur de l'action : le Timer pour le zoom et le bouton btnOpen qui contient tout le taf (une main routine et 5 sous-routines incrustées dans la partie var)
    • à la fin les fonctions des boutons annexes (choix de l'image affichée [si multi], zoom on/off, transparence on/off)
    • et à la fin de la fin, un bonus, et des vieilles notes.

    5- Concernant l'affichage du mémo sous XP (chose curieuse, les résultats sous XP utilisent deux machines virtuelles créées depuis la même source et pourtant le rendu du texte n'est pas le même -- go figure...), me suis rendu compte après la copie d'écran que ça pouvait être correct (mais vraiment petit -- là on est à 6, plus grand et les lignes vont se dédoubler dessous, très moche et pas confortable) avec "Courier New", 'fin bon, z'êtes des grands garçons je vous laisse gérer ça.
    Nom : compar_memo_2xp_lin.png
Affichages : 250
Taille : 29,4 Ko

    6- Il reste un (microscopique) souci, que je n'arrive pas encore à cerner : certaines images .bmp ont un comportement curieux quand j'active la transparence du TImage qui les affiche :
    Nom : compar_transp_bmp24.png
Affichages : 306
Taille : 172,2 Ko
    J'en ai mis une dans le paquet, vous verrez bien...

    Que dire d'autre ? Que je retourne à ce qui a motivé ce projet et ce post (je fais comme les procs et les routines : je dépile, ), à savoir l'étude des filtres de resampling (anapurna, je n'oublie pas ton zip).

    Merci à tous pour les coups de main, astuces, formules magiques et autres incantations,

    Yves, tu trouveras dans le bonus comment récupérer les données Exif.

  12. #12
    Membre Expert
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Billets dans le blog
    2
    Par défaut
    Salut Jp, sympa, les streams qu'elle joie ! j'aime bien comment tu les as utilisés pour "contourner" le TBitmap, simple et efficace. La pipette avec le zoom excellent.

    Sinon il semblerai que les fichiers suivant soient en réalité des 24bits et non des 32bits

    Nom : 2017-06-12_225934.jpg
Affichages : 239
Taille : 26,8 Ko

    J'ai les même infos avec mon projet au cas ou.

    mais pourquoi certains bmp24 ont de la transparence ? Mystère...
    Tu aurais un fichier ou 2 pour tester ?

    ha oui, j'allais oublié juste le truc pour avoir un affichage correcte avec la transparence avec les BMP faut que tu "pre-multiplis" tes valeurs, comme on en à déja discuté.

    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 131
    Par défaut
    Yop !

    [EDIT] j'ai mis à jour le post d'hier matin, je laisse cependant le fichier avec les 2 nouveaux .bmp ici pour ceux qui auraient téléchargé hier le mauvais .zip. Merci encore à BeanzMaster pour sa vigilance [/EDIT]

    Citation Envoyé par BeanzMaster Voir le message
    Salut Jp, sympa, les streams quelle joie ! j'aime bien comment tu les as utilisés pour "contourner" le TBitmap, simple et efficace. La pipette avec le zoom excellent.
    Merci pour tes tests, tes compliments et ton coup d'œil de lynx, ou de sioux ! Bien vu les bmp32 qui sont des 24...


    Citation Envoyé par BeanzMaster Voir le message
    Sinon il semblerait que les fichiers suivants soient en réalité des 24bits et non des 32bits
    Je mérite des baffes !
    Dans ce zip, les 2 fichiers incriminés, en attendant que je régénère une archive complète : 2bmp_32bits.zip


    Citation Envoyé par BeanzMaster Voir le message
    mais pourquoi certains bmp24 ont de la transparence ? Mystère...
    Tu aurais un fichier ou 2 pour tester ?
    Il y en a un, le 200x150x24_T.bmp

    Citation Envoyé par BeanzMaster Voir le message
    ha oui, j'allais oublier juste le truc pour avoir un affichage correct avec la transparence avec les BMP faut que tu "pre-multiplies" tes valeurs, comme on en a déjà discuté.

    A+
    Aucun souvenir ! Tu peux me rafraîchir la mémoire ?

    Merci, et encore désolé pour l'erreur sur ces deux fichiers.

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

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

    ça avance, et drôlement bien je trouve !
    En théorie c'est fini, bientôt le zip pour les gens intéressés, pour les faire patienter un autre gif (désolé, Lena -- on dirait qu'elle a une maladie de peau, la pauvrette, ) où se succèdent une image bmp puis la même modifiée avec un M rouge puis l'indication des différences (M blanc) puis le même fichier enregistré en jpeg (qualité 100 %), puis le jpeg modifié (M mauve) et enfin les différences jpeg et on voit bien les artefacts de ce type de compression.

    Nom : compars.gif
Affichages : 315
Taille : 233,6 Ko
    (un microscopique bug est présent tout en bas à gauche, découvert grâce au gif, justement, et corrigé, pas de panique )

    Il me reste deux bricoles à voir :
    • certains bitmaps que j'ai générés avec The Gimp embarquent une information de transparence même en pf24bit, que je n'arrive pas à trouver mais que le TImage est capable d'afficher si je lui bascule .Transparent := True; un mystère...
    • tout tester sous XP.


    MP à tourlourou, s'il passe par là : ai trouvé une petite unité Exif qui, en trente secondes (le plus long a été de saisir la proc de récup des infos), m'a trouvé tout ça dans une 'tof shootée par le vieux Canon de mon fils :
    Code text : 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
    Valid : Yes
    ImageDesc : 
    Make : Canon
    Model : Canon EOS 450D
    Orientation : 1
    OrientationDesc : Normal
    Copyright : 
    DateTime : 2013:06:30 16:41:04
    DateTimeOriginal : 2013:06:30 16:41:04
    DateTimeDigitized : 2013:06:30 16:41:04
    UserComments : 
    Software : 
    Artist : 
    Exposure : 1/50 seconds
    ExposureProgram : 3
    ExposureProgramDesc : Normal Program
    FStops : 8.0
    ShutterSpeed : 1/49 seconds
    Aperture : 6.0
    MaxAperture : 
    CompressedBPP : 
    PixelXDimension : 176
    PixelYDimension : 32
    XResolution : 72
    YResolution : 72
    MeteringMode : 2
    MeteringMethod : Center Weighted Average
    LightSource : 0
    LightSourceDesc : 
    Flash : 16
    FlashDesc : No Flash
    ISO : 100
    Elle est cachée là, la coquine
    Bon, c'est en teuton mais il n'y a pas de souci


  15. #15
    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
    Hello, unité EXIF bien vue, merci !
    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 !

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

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

    je vais essayer de vous la faire courte, je vous préviens c'est un truc à s'arracher les cheveux (heureusement j'en ai beaucoup).
    Prêts ?

    Hier j'ai donné deux liens, j'avais noté d'autres codes au cours de mes pérégrinations sur le web, hier soir tard j'ai testé, ce matin j'ai testé dans XP les tests d'hier, il en sort ça, avec un bon point pour XP, les défauts sont les mêmes que sous Linux :
    • checkifdifferent = résultat ok fic24 comme fic32
    • utilise des streams = ne détecte pas les fichiers différents, fic24 comme fic32
    • utilise pintegerarray = détecte différents les fichiers identiques, fic24 comme fic32
    • embarcadero utilise comparemem = idem dessus


    Il y en a donc un qui fonctionne correctement ! Verrait-on le bout du tunnel ? Son algo, très basique :
    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
      function CheckIfDifferent(bmp1, bmp2: TBitmap): boolean;
      // http://freedelphitutorials.blogspot.fr/2015/04/how-to-compare-2-images.html
      var
        p1, p2  : pByte;
        h, w    : integer;
        checkRes: boolean;
      begin
        checkRes := false;
        h:=0;
        while not (checkRes) and (h < bmp1.Height) do begin
          p1 := bmp1.Scanline[h];
          p2 := bmp2.Scanline[h];
          w := 0;
          while not (checkRes) and (w < bmp1.Width) do begin // on dirait qu'on parcourt par bytes -- il est faux ce parcours ?
            if Integer(p1^) <> Integer(p2^)
            then checkRes := true 
            else begin inc(p1); inc(p2); end;
            inc(w);
          end;  
        result := checkRes;
      end;
    Testé donc avec fichier 24 bits, fichier 32 bits, sous XP et Linux, ça fonctionne, pas d'AV, bien bien bien.

    Sauf que je suis curieux, et que je voulais voir où les détections se passaient. Bien m'en a pris de vouloir logguer h et w, j'ai découvert un truc de fou, que je ne soupçonnais pas.
    J'ai rajouté un paramètre à la fonction CheckIfDifferent(var BytesPerPixel: integer; bmp1, bmp2: TBitmap): boolean; et je vous laisse lire les commentaires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //      for w := 0 to (bmp1.Width * BytesPerPixel)-1 do begin // on dirait qu'on parcourt par bytes --> modif en multipliant par BPP
    // dessous forcé pour test avec fic32 (car BytesPerPixel à 4 [fic32] montre 3 bytes only par pixel dans le log...)
          for w := 0 to (bmp1.Width * 3)-1 do begin // juste pour voir
            if Integer(p1^) <> Integer(p2^)
            then begin memo1.lines.Add(inttostr(h)+' '+inttostr(w)+' '+inttostr(Integer(p1^))+' '+inttostr(Integer(p2^))); end;
    // confirmé : le byte alpha n'existe pas dans le log
    // donc ce qui est pris en compte dans les couches de bas niveau auxquelles je n'accède pas,
    // c'est un PixelFormat à pf24bit malgré le fichier 32 bits et le PixelFormat du header à pf32bit...
            inc(p1); inc(p2);
          end;
    Tout ça pour dire que si les bytes RGB d'un pixel sont identiques mais que son canal Alpha est différent, ça ne sera pas détecté.
    Au final, cette histoire de Scanline c'est pas glop

    Va falloir trouver autre chose, mais comme noté plus haut,
    • utilise des streams = ne détecte pas les fichiers différents, fic24 comme fic32
    • utilise pintegerarray = détecte différents les fichiers identiques, fic24 comme fic32
    • embarcadero utilise comparemem = idem dessus


    J'avais dit "3 jours" dans le titre (ah tiens, on me l'a modifié ), je risque de dépasser...
    (d'autant plus que j'ai découvert au passage que le contenu des fichiers BMP n'était pas toujours ce qu'on demandait et supposait -- mais je ne sais pas encore si je poste ça ici ou dans des sous-forums plus appropriés sur l'image, ou si c'est The Gimp qui nous fait un caca nerveux...)

  17. #17
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut jp

    tu te fais des nœuds à la tète tout seul. je m'explique
    tu peut très bien faire ton test sur le width mais dans ta boucle pour chaque tour in te faudra vérifier le pixel et sa définition
    si c'est du 32 le pixel = 4 byte si c'est du 24 le pixel = 3 byte inférieur a 16 = 1 byte
    il est donc recommandé de comparer les fichier ayant les même caractéristiques
    si ce n'est pas le cas il faut que tu passe en paramètre les caractéristique de chaque fichier
    après pour comparer ce qui est comparable il te faut transformer tes éléments en element de même caractéristique

    imaginons que pour plus de facilite je défini mon propre enregistrement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       TmaRecord = Record 
          Posi      = Integer;
          Rouge   = Byte;
          Vert     = Byte;
          Bleu     = Byte;
          Alpha   = Byte;
      end;
    Tu crée Pour chaque définition une fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
       Fonction Transform24ToPerso(Datas : Pointer;Position : integer) :TmaRecord; 
       Fonction Transform16ToPerso(Datas : Pointer;Position : integer) :TmaRecord; 
       Fonction Transform1ToPerso(Datas : Pointer;Position : integer)   :TmaRecord; 
       Fonction Transform32ToPerso(Datas : Pointer;Position : integer) :TmaRecord;
    ...
    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
     
      Fonction Transform24ToPerso(Datas : Pointer;Position : integer) :TmaRecord; 
      begin
         Result.Posi     := Position;
         Result.Rouge  := Datas[Position]^
         Result.Vert    := Datas[Position+1]^
         Result.Bleu    := Datas[Position+2]^
         Result.Alpha  := 255;
         inc(Datas,3);
      End;
      //////////////////////////////////
      Fonction Transform32ToPerso(Datas : Pointer;Position : integer) :TmaRecord; 
      begin
         Result.Posi     := Position;
         Result.Rouge  := Datas[Position]^
         Result.Vert     := Datas[Position+1]^
         Result.Bleu     := Datas[Position+2]^
         Result.Alpha   := Datas[Position+3]^;
         inc(Datas,4);
      End;
      // ...
      TransformToPerso(Datas : Pointer;Position,BytesPerPixel : integer) :TmaRecord;
      begin
         Case BytesPerPixel of 
           1    : Result  :=  Transform1ToPerso(Datas,Position);
           16  : Result  :=  Transform16ToPerso(Datas,Position);
           24  : Result  :=  Transform24ToPerso(Datas,Position);
           32  : Result  :=  Transform32ToPerso(Datas,Position);
           ....
        else
          fillechar(Result,sizeof(TmaRecord),0) ;
        end;
       end;
      //----------------------------------------------
    donc imaginons que tu est deux images n'ayant pas le meme format il te faudra faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        checkRes := False;
    //   Width := Min( bmp1.Width, bmp2.Width);// on prend la plus petite longueur
       checkRes := bmp1.Width = bmp2.Width; // on verifie que les taille sont identique
       p1 := bmp1.Scanline[h];
       p2 := bmp2.Scanline[h];
       While not(checkRes) and W < Width do 
       begin
          c1 := TransformToPerso(p1,w,24);
          c2 := TransformToPerso(p2,w,32);
          if  c1 <> c2 Then 
             checkRes := False;
          Inc(w); 
       End;
    voila globalement la marche à suivre

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 131
    Par défaut
    Citation Envoyé par anapurna Voir le message
    il est donc recommandé de comparer les fichier ayant les même caractéristiques
    C'est ex-ac-te-ment ce que je fais avant même d'appeler la fonction de comparaison, pas de souci de ce côté-là.
    J'attends que les choses simples fonctionnent pour passer aux compliquées.

    Citation Envoyé par anapurna Voir le message
    si c'est du 32 le pixel = 4 byte si c'est du 24 le pixel = 3 byte inférieur a 16 = 1 byte
    Pourquoi 1 byte ? J'ai déjà vu des paddings à 2 ou 3 bytes...

    Citation Envoyé par anapurna Voir le message
    tu te fais des nœuds à la tête tout seul.
    Euh, pas tant que ça, je crois. En fait c'est ScanLine qui me met la pagaille : quand je prends un fichier 32 bits et que je fais tourner ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for w := 0 to (bmp1.Width * BytesPerPixel)-1 do begin 
      if Integer(p1^) <> Integer(p2^) then 
        memo1.lines.Add(inttostr(h)+' '+inttostr(w)+' '+inttostr(Integer(p1^))+' '+inttostr(Integer(p2^)));
    je vois bien avec mes yeux dans le mémo qu'il n'y a que 3 bytes par pixel, alors que j'en vois 4 avec le même fichier dans un afficheur hexa.

    D'ailleurs c'est ce que je disais hier :
    il faut que j'active RGBTriple pour comparer des fichiers 32 bits ! Ça ne choque personne ? Genre il faut que je loue un bus de 24 places pour trimbaler 32 gamins au parc.
    Sous-entendu (maintenant j'ai compris !) un gamin sur 4 (le gamin alpha ! ) est laissé au bas des marches de la porte du bus.

    Pas plus à dire...

    Ah si ! J'ai testé ton helper, il fonctionne mais au final je vais zapper Scanline pour attaquer directement la mémoire avec les infos remontées par BitmapInfoHeader.
    Là je contrôlerai tout du début à la fin.

  19. #19
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 933
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 933
    Par défaut
    Citation Envoyé par Jipété Voir le message
    je vois bien avec mes yeux dans le mémo qu'il n'y a que 3 bytes par pixel
    Et comment peux-tu voir ça dès lors que tu lis systématiquement 4 octets integer(p1^)

    De plus et du fait que la boucle soit fausse (inc(p1) décale de un octet et non de un pixel) tu dois obligatoirement te retrouver à un moment ou un autre avec des valeurs supérieures ou égales à 224 (à moins que l'image soit noire).

  20. #20
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    quand c'est inférieur à 16 c'est du mono dans mon souvenir donc
    1 byte suffisais a définir le pixel
    au delà c’était un index dans une table ou la couleur était défini à l'avance
    j'ai donné ce code a titre d'exemple il est pas a prendre tels quel
    il ne tiens pas compte de la compression non plus et diverses petite subtilité



    Ps : sur le liens d'hier c'est normal tu compare que des triplet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       if not CompareMem(Pr, Ps, SizeOf(TRGBTriple)) then

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. comparer deux fichier .xls
    Par oursquetaire dans le forum Excel
    Réponses: 6
    Dernier message: 06/07/2006, 16h52
  2. [JDOM] Comparer deux fichiers XML en Java
    Par calimero2611 dans le forum Format d'échange (XML, JSON...)
    Réponses: 5
    Dernier message: 30/06/2006, 11h19
  3. Comparer deux fichier
    Par Taz_8626 dans le forum Langage
    Réponses: 3
    Dernier message: 20/06/2006, 11h46
  4. comparer deux fichiers avec une api windows
    Par sweetdreamer dans le forum Windows
    Réponses: 4
    Dernier message: 25/05/2006, 22h10
  5. Fonction c qui compare deux fichiers ???
    Par babyface dans le forum C
    Réponses: 4
    Dernier message: 19/11/2005, 13h07

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