Bonjour, je souhaite comparer 2 images BMP ou JPG pour savoir si c'est les meme. Ces 2 images sont toujours des print screen. merci de votre aide si vous avez la réponse !
Bonjour, je souhaite comparer 2 images BMP ou JPG pour savoir si c'est les meme. Ces 2 images sont toujours des print screen. merci de votre aide si vous avez la réponse !
Bonjour,
peux-tu être plus précis: s'agit-il d'un comparatif entre une image en format BMP et la même image mais en format JPG ?
Ou s'agit-il plus simplement d'un comparatif entre 2 images BMP ou 2 images JPG ?
oui oui c'est bien des images de meme type !
Bonjour,
à première vue, je dirais que l'utilisation d'une scrutation pixel par pixel des bitmaps pourrait être la solution.
Pour éviter du traitement superflu, il faudrait déjà comparer les hauteurs et largeurs des 2 bitmaps. Si déjà là c'est différent, alors c'est pas la peine de continuer.
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 for( y = hauteur_bitmap; y >= 0; y-- ) { for( x = largeur_bitmap; x >= 0; x-- ) { Couleur_bmp1 = MonBitmap1->Canvas->Pixels[x][y]; Couleur_bmp2 = MonBitmap2->Canvas->Pixels[x][y]; if( Couleur_bmp1 <> Couleur_bmp2 ) { // Pas pareil... break; } } }
ouai c cool ce code fonctionne mais il ni aurait pas une methode plus rapide ? c'est extrement lent ....
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap; Graphics::TBitmap *Bitmap2 = new Graphics::TBitmap; Bitmap1->LoadFromFile("1.BMP"); Bitmap2->LoadFromFile("2.BMP"); for(int y = 0; y <= Bitmap1->Height; y++) for(int x = 0; x <= Bitmap2->Width; x++) if(Bitmap1->Canvas->Pixels[x][y] != Bitmap2->Canvas->Pixels[x][y]) { ShowMessage("Les images ne sont pas identiques !"); return; } ShowMessage("Les images sont identiques");
Pour l'instant, je galère comme toi.
Je cherche à 'ombrer' une zone d'un bitmap en fonction d'un second bitmap situé au-dessus du premier.
Je n'ai pas trouvé de système pour bidouiller les octets mémoire contenant l'image.
Pourtant cela doit exister mais il faut que je trouve le moyen d'accéder aux pixels d'une façon plus globale qu'à travers la méthode Pixel[x][y].
J'en viens à regretter le temps de mon ATARI 1040 ST avec lequel on accédait directement à la mémoire vidéo![]()
j'ai vu qu'il fallait utiliser ScanLine de TBitmap pour accelerer le travail mais j'arrive pas à l'utiliser pour comparer mes pixels ......![]()
Salut !
Pixels[X][Y] est efficace pour toutes les définitions de bitmap.
ScanLine[Y] peut être utilisé sur des bitmaps 24 bit, mais pose un sérieux problème pour la comparaison de deux bitmaps 8 bit du fait qu'on compare des index de couleurs et non les couleurs elles-mêmes.
Pour des bitmaps 24 bit, avec ScanLine[Y], il suffit de comparer les composantes pour chaque pixel. Il faudrait voir si on a intérêt à remplacer 3 tests par un seul test (avec COLORREF obtenu à l'aide de RGB)...
A plus !
Salut !
Moi aussi mais on y arrive quand même avec un PC !J'en viens à regretter le temps de mon ATARI 1040 ST avec lequel on accédait directement à la mémoire vidéo![]()
A plus !
alors comment c'est possible de comparer 2 images très rapidement ?
Salut !
Par exemple, en faisant ainsi :
A plus !
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 void __fastcall TForm1::SpeedButton1Click(TObject *Sender) { Graphics::TBitmap *B1 = Image1->Picture->Bitmap; B1->PixelFormat = pf24bit; Graphics::TBitmap *B2 = Image2->Picture->Bitmap; B2->PixelFormat = pf24bit; Byte *P1; Byte *P2; if((B1->Width == B2->Width) && (B1->Height == B2->Height)) { for(int y = 0; y < B1->Height; y++) { P1 = (Byte*)B1->ScanLine[y]; P2 = (Byte*)B2->ScanLine[y]; for(int x = 0; x < B1->Width; x++) { if((P1[0] != P2[0]) || (P1[1] != P2[1]) || (P1[2] != P2[2])) return; P1 = P1 + 3; P2 = P2 + 3; } } ShowMessage("Identiques"); } }
Salut !
Sinon, pour aller encore plus vite on peut développer autrement.
On sait qu'ici on perd du temps à tester Byte par Byte, pour ce qui est des composantes.
Cette organisation par triplets n'est d'ailleurs qu'anecdotique vis à vis du traitement que l'on cherche à effectuer ici !
L'idée est de mettre en place un algo qui va procéder par granulations successives.
C'est à dire commencer par traiter des int puis des short (s'il en reste) puis un Byte s'il en reste un !
Je ne sais pas si tu me suis ?
"If You Want Blood..."à plus !
Salut, je vais d'abord voir ce code .... je verrais ensuite pour faire plus rapidement si je peux, car je suis pas sur d'avoir tout compris mais ce code m'aidera peut être ! merci ... ("If you want blood, you've got it")![]()
ouè c'est cool ça fonctionne ... des questions tout de meme: Pourquoi on incrémente P1 et P2 dans la boucle de x ? P1[0], P1[1], P1[2] sont les couleurs RVB ? merci !
Salut !
Voici ce qui tourne (au moins) deux fois plus vite que ce que j'ai donné précédemment :
Pour les questions :
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 void __fastcall TForm1::SpeedButton2Click(TObject *Sender) { Graphics::TBitmap *Bmp1 = Image1->Picture->Bitmap; Bmp1->PixelFormat = pf24bit; Graphics::TBitmap *Bmp2 = Image2->Picture->Bitmap; Bmp2->PixelFormat = pf24bit; int *I1; short *S1; Byte *B1; int *I2; short *S2; Byte *B2; int nbInt; int nbByte; int nbShort; if((Bmp1->Width == Bmp2->Width) && (Bmp1->Height == Bmp2->Height)) { nbInt = Bmp1->Width * 3; nbByte = nbInt & 1; nbInt = nbInt / 2; nbShort = nbInt & 1; nbInt = nbInt / 2; for(int y = 0; y < Bmp1->Height; y++) { I1 = (int*)Bmp1->ScanLine[y]; I2 = (int*)Bmp2->ScanLine[y]; for(int x = 0; x < nbInt; x++) { if(*I1 != *I2) return; I1++; I2++; } //Changement de granularité pour la suite S1 = (short*)I1; S2 = (short*)I2; if(nbShort) { if(*S1 != *S2) return; S1++; S2++; } //Changement de granularité pour la suite if(nbByte) { B1 = (Byte*)S1; B2 = (Byte*)S2; if(*B1 != *B2) return; } } ShowMessage("Identiques"); } }
On y fait P + 3 à cause des composantes (RGB), x ne compte que les pixels !
A plus !
jte remercie beaucoup pour ce code, même si j'ai pas tout compris .... Je voudrais quand meme quelques explications pour comprendre.
Ce que j'ai compris :
Pour toutes les lignes de pixel de l'image
- Fais pointer P1 sur chaque ligne
- Pour tous les pixels de la ligne
- P1[0] contient le rouge; P1[1] le vert et P1[2] le bleu
- Increment de P1 pour passer au pixel suivant
????
Salut,
moi je viserai plus sur le système de comparaison de Bytes.
J'avais codé un bout d'appli de comparaison d'images/fichiers rapidement.
En fait je calculais le MD5 du fichier (logiquement unique à chaque fichier...) et il te suffit alors de comparer ce MD5 de chaque fichiers entre eux.
Voilà, si tu cherches des sources de MD5 pour fichier, je pourrai te filer un lien.
+++
Salut !
Chez moi l'ordre des composantes c'est :
P[0] Blue
P[1] Green
P[2] Red
J'ai corrigé l'erreur dans une autre réponse d'une autre discussion (niveau de gris).
Pour le pointeur, on est bien obligé de faire + 3 puisque la boucle traite des triplets d'octets (1 pixel = 3 octets) et que le pointeur pointeur sur le type Byte.
La boucle x ne fait que décompter les pixels.
A plus !
hi,
can you provide me the whole code soucre for the comparaison algorithm, quel sont tibrairies que je dois inclure pour Graphics...
Partager