Bonsoir,
Je galère depuis plusieurs jours pour un problème très simple à priori : lire une image au format BMP en couleur, et à partir de cela en créer une en noir et blanc (pas en niveau de gris), travailler dessus et ensuite l'enregistrer. Ceci est juste un petit préalable à un programme de traitement d'image sur lequel je travaille
Après deux façons de procéder que j'ai abandonné, j'ai décidé de lire et d'écrire directement les fichiers en binaire, en stockant les données dans des tableaux, sans utiliser aucune fonction graphique. En fait ce n'est pas plus mal car mon programme n'a pas besoin d'afficher les images
Donc après une nouvelle fois de longues recherches et essais, je tombe encore sur un os. Ce code ne fonctionne pas, le fichier resultat est illisible (les logiciels comme paint ou la visionneuse windows me disent que le fichier est corrompu); je ne vois pas où est l'erreur
j'ai passer les fichiers à la loupe dans un éditeur hexadécimal et pareil, je ne comprends pas où est le problème, les entêtes sont correctes, les données au bon endroit et de bonne longueur :
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 Imports System Imports System.IO Imports System.Security.Permissions Public Class Form1 Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click 'Ici on va lire et écrire directement un fichier BMP sans passer par les fonctions graphiques Dim mes As String Dim FichierImageDepart As String Dim FichierImageResultat As String Dim tmpb As Byte Dim tmps As String Dim tmpi As UInt16 Dim tmpl As UInt32 Dim i As Integer Dim Largeur As UInt32 Dim Hauteur As UInt32 Dim nBitsParPixel As UInt16 Dim tailleImageOctets As UInt32 Dim nOctetsParLigne As UInt32 Dim nOctetsParLigne2 As UInt32 Dim x As UInt32 Dim y As UInt32 FichierImageDepart = My.Application.Info.DirectoryPath + "\ImageALire_GRIS.BMP" 'FichierImageDepart = My.Application.Info.DirectoryPath + "\ImageALire_GRIS2.BMP" FichierImageResultat = My.Application.Info.DirectoryPath + "\ImageResultat4.BMP" Dim binReader As New BinaryReader(File.Open(FichierImageDepart, FileMode.Open)) 'Lecture de l'entête 'Lecture des deux octets descripteur de type tmps = binReader.ReadChars(2) If tmps <> "BM" Then MsgBox("Le fichier " + FichierImageDepart + "n'est pas de type BMP") Exit Sub End If 'Taille du fichier tmpl = binReader.ReadUInt32 'Reservé tmpl = binReader.ReadUInt32 'Offset de l'image tmpl = binReader.ReadUInt32 'Taille de l'entête image tmpl = binReader.ReadUInt32 'Dimenssions de l'Image Largeur = binReader.ReadUInt32 Hauteur = binReader.ReadUInt32 'Nombre de plan tmpi = binReader.ReadInt16 'Nombre de bits par pixel nBitsParPixel = binReader.ReadInt16 If nBitsParPixel <> 24 Then MsgBox("Le fichier " + FichierImageDepart + "n'est pas en couleurs 24 bits, abandon de la lecture") Exit Sub End If 'Methode de compression tmpl = binReader.ReadUInt32 If tmpl <> 0 Then MsgBox("Le fichier " + FichierImageDepart + "est compressé, abandon de la lecture") Exit Sub End If 'Taille de l'image en octets tailleImageOctets = binReader.ReadUInt32 'Résolution de l'image tmpl = binReader.ReadUInt32 tmpl = binReader.ReadUInt32 'Couleurs utilisées tmpl = binReader.ReadUInt32 'Couleurs importantes : tmpl = binReader.ReadUInt32 ' 'Lecture de l'image Dim dataImage() As Byte = binReader.ReadBytes(tailleImageOctets) binReader.Close() mes = "Résolution = " + Format(nBitsParPixel) + " bits/pixel" + vbCrLf mes = mes + "Largeur = " + Format(Largeur) + " pixels" + vbCrLf mes = mes + "Hauteur = " + Format(Hauteur) + " pixels" + vbCrLf mes = mes + "Nb pixels image utile = " + Format(Largeur * Hauteur) + " pixel" + vbCrLf mes = mes + "Nb octets image utile = " + Format(Largeur * Hauteur * 3) + " octets" + vbCrLf mes = mes + "Taille de l'image = " + Format(tailleImageOctets) + " octets" + vbCrLf MsgBox(mes) nOctetsParLigne = Fix((Largeur * 3 + 3) / 4) * 4 'Génération de la nouvelle image : nOctetsParLigne2 = Fix((Largeur + 31) / 32) * 4 'nOctetsParLigne doit être multiple de 4 MsgBox("nOctetsParLigne = " + Format(nOctetsParLigne2)) Dim dataImage2(nOctetsParLigne2 * Hauteur) As Byte 'calcul de l'image en N&B à partir de l'image en couleur: For y = 0 To Hauteur - 1 i = 1 tmpi = 0 tmpb = 0 For x = 0 To Largeur - 1 If i = 256 Then i = 1 tmpb = 0 dataImage2(tmpi + nOctetsParLigne2 * y) = tmpb tmpi = tmpi + 1 End If 'Calcul basique, juste une des trois couleurs RBV If dataImage(y * nOctetsParLigne + x * 3) > 128 Then 'On allume le pixel tmpb = tmpb + i End If i = 2 * i Next 'Le dernier octet : dataImage2(tmpi + nOctetsParLigne2 * y) = tmpb 'Les octets à 0 pour avoir une ligne multiple de 4 octets : If tmpi < nOctetsParLigne2 - 1 Then For i = tmpi + 1 To nOctetsParLigne2 - 1 dataImage2(i + nOctetsParLigne2 * y) = 0 Next End If Next Dim binWriter As New BinaryWriter(File.Open(FichierImageResultat, FileMode.Create)) 'Ecriture de l'entête tmpi = &H4D42 : binWriter.Write(tmpi) 'Taille du fichier tmpl = 54 + 1 + nOctetsParLigne2 * Hauteur binWriter.Write(tmpl) 'Reservé tmpl = 0 : binWriter.Write(tmpl) 'Offset de l'image tmpl = 54 : binWriter.Write(tmpl) 'Taille de l'entête image tmpl = 40 : binWriter.Write(tmpl) 'Dimenssions de l'Image binWriter.Write(Largeur) binWriter.Write(Hauteur) 'Nombre de plan tmpi = 1 : binWriter.Write(tmpi) 'Nombre de bits par pixel tmpi = 1 : binWriter.Write(tmpi) 'Methode de compression tmpl = 0 : binWriter.Write(tmpl) 'Taille de l'image en octets tmpl = nOctetsParLigne2 * Hauteur binWriter.Write(tmpl) 'Résolution de l'image tmpl = 3780 : binWriter.Write(tmpl) : binWriter.Write(tmpl) 'Couleurs utilisées tmpl = 0 : binWriter.Write(tmpl) 'Couleurs importantes : tmpl = 0 : binWriter.Write(tmpl) 'Les données binWriter.Write(dataImage2) binWriter.Close() MsgBox("Traitement terminé") End Sub End Class
NB : le fait que les données n'aient pas la bonne valeur est encore un autre problème mais pour le moment ce qui est important est de pouvoir générer un BMP valide, histoire de ne plus travailler en aveugle...
merci
A+
Partager