Bonjour à tous,
Je me crée une petite bibliothèque de comparaison d'image dans le cadre d'un projet. Une des class est censée vérifier que deux image sont identiques en taille, format, résolution, ...
Pour la comparer pixels par pixels, j'utilise la fonction suivante qui trouve les pixels différent
En principe si le résultat est à 0 j'ai une image identique au pixels près.
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 protected static IList<Point> GetDiffPixels(Image img1, Image img2) { Bitmap bmp1 = (Bitmap)img1; Bitmap bmp2 = (Bitmap)img2; IEnumerable<int> widthRange = Enumerable.Range(0, img1.Width); IEnumerable<int> heightRange = Enumerable.Range(0, img1.Height); List<Point> result = widthRange .SelectMany(x => heightRange, (x, y) => new Point(x, y)) .Select(point => new { Point = point, Pixel1 = bmp1.GetPixel(point.X, point.Y), Pixel2 = bmp2.GetPixel(point.X, point.Y) }) .Where(pair => pair.Pixel1 != pair.Pixel2) .Select(pair => pair.Point) .ToList(); return result; }
J'ai également fait un autre test sur base de deux images identiques au pixels près et au même format sur leur stream par le code suivant :
Et la le résultat est étonnant.
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 public static Stream ImageToStream(Image image) { ImageFormat imgFormat = ImgUtils.GetFormat(image); MemoryStream ms = new MemoryStream(); image.Save(ms, imgFormat); return ms; } public static bool CompareStreamImage(Image img1, Image img2) { using( Stream stream1 = ImageToStream( img1 ) ) { using(Stream stream2 = ImageToStream( img2 ) ) { return CompareStream(stream1, stream2); }} } public static bool CompareStream(Stream a, Stream b) { if (a == null || b == null) throw new ArgumentNullException(a == null ? "a" : "b"); if (a == b) return true; if (a.Length != b.Length) //TODO: comment faire la différence si longueur différente ou si pas la même comparaison après return false; for (int i = 0; i < a.Length; i++) { int aByte = a.ReadByte(); int bByte = b.ReadByte(); if (aByte.CompareTo(bByte) != 0) return false; } return true; }
En effet, la comparaison au pixels près est identique mais l'analyse du stream est différent au niveaux de la longeur des streams.
Les questions sont donc
l'image est-elle différente ou non?
Qu'est ce qui peut faire que deux images identiques au pixels près peuvent avoir des streams différent?
Sur quoi puis-je me baser pour m'assurer que deux images sont identiques si les méthodes ci-avant donnent des résultat différent?
Merci de votre aide et en espérant avoir été clair sur le problème rencontré.
Partager