Non le début est:
ÿØÿà JFIF ÿÛ C ÿÛ C ÿÀ —b" ÿÄ
en fait il s'agit des photos issues du site http://www.daylife.com/ , je voudrais faire un logiciel pour les classer par date de création
Non le début est:
ÿØÿà JFIF ÿÛ C ÿÛ C ÿÀ —b" ÿÄ
en fait il s'agit des photos issues du site http://www.daylife.com/ , je voudrais faire un logiciel pour les classer par date de création
@tourlourou : pour info, j'viens d'ouvrir une image qui contient de l'exif, et moi, j'ai FF D8 FF E0 (je retrouve cependant 45 78 69 66 un peu plus loin...)
@mecyber25 : Ouvre une de tes images avec un programme comme celui-ci...
Le début est du fichier jpg est:
ÿØÿà JFIF ÿÛ C
Je lis
FF D8 FF E0 00 10 4A 46
mais ne trouve pas 45 78 69 ...etc
@ Whiler et mecyber25 : les fichiers dont vous me parlez débutent par une section JFIF (marqueur application APP0 = $FFE0) :
FF D8 = header jpeg
FF E0 = marqueur JFIF
20 10 = offset section suivante ($1020)
4A 46 49 46 20 = 'JFIF' mais il devrait y avoir #0 au lieu de #20 derrière
01 01 = version JFIF 1.01
20 01 = là, ça se gâte par rapport à ce qu'on attend !
20 01
20
FF DB = marqueur jpeg SOI
[EDIT = les $20 doivent être des espaces remplaçant des #0]
Le format JFIF n'est pas censé contenir d'informations telles que la date de prise de vue. Mais il peut y avoir une section privée APP0 qui pourrait (pourquoi pas ?) en renfermer (format IPTC ?).
Quel est l'intérêt de clichés JPEG au format JFIF + données IPTC plutôt qu'EXIF avec répertoire IPTC ?
@ mecyber25 : je suis intéressé par ton cliché (ou son entête s'il est confidentiel).
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 !
je viens d'en charger une : elle possède une section APP13 (marqueur $FFED) de données Photoshop-style avec données IPTC ; donc pas de données Exif...
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 !
Je te suggère de ne pas renoncer à la programmation au seul motif que la fonction Built-In qui t'aurait convenue n'existe pas... il faut parfois plonger les mains dans le cambouis !
Voici un code en PHP, qui donne les principaux paramètres ; il doit être assez facile de s'en inspirer pour parser la section APP13 d'un fichier jpeg. C'est un exercice qui n'a pas l'air hors d'atteinte.
Mais je présume qu'il doit exister en Delphi des librairies qui le font déjà : je n'ai pas le temps de faire une recherche plus approfondie.
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249 <?php /** * Manipulate IPTC tags * * @date 08-20-2010 * @author ShevAbam */ class IptcManager { public $file = ''; public $listTags = array(); /** * Constructor */ public function __construct() { $this->listTags(); } /** * Sets the image file * * @param string $filename Path of the image file * @return object */ public function setFile($filename) { if (!empty($filename) && is_file($filename)) $this->file = $filename; return $this; } /** * Sets the IPTC tags * * @return void */ public function listTags() { // Most common tags. You can redefine this method by extending the class $getAll = array( array('id' => 1, 'name' => 'Object type', 'tag' => '2#003'), array('id' => 2, 'name' => 'Object attribute', 'tag' => '2#004'), array('id' => 3, 'name' => 'Title', 'tag' => '2#005'), array('id' => 4, 'name' => 'Edit status', 'tag' => '2#007'), array('id' => 5, 'name' => 'Editorial update', 'tag' => '2#008'), array('id' => 6, 'name' => 'Urgency', 'tag' => '2#010'), array('id' => 7, 'name' => 'Subject reference', 'tag' => '2#012'), array('id' => 8, 'name' => 'Category', 'tag' => '2#015'), array('id' => 9, 'name' => 'Supplemental categories', 'tag' => '2#020'), array('id' => 10, 'name' => 'Fixture identifier', 'tag' => '2#022'), array('id' => 11, 'name' => 'Keywords', 'tag' => '2#025'), array('id' => 12, 'name' => 'Location code', 'tag' => '2#026'), array('id' => 13, 'name' => 'Location name', 'tag' => '2#027'), array('id' => 14, 'name' => 'Release date', 'tag' => '2#030'), array('id' => 15, 'name' => 'Release time', 'tag' => '2#035'), array('id' => 16, 'name' => 'Expiration date', 'tag' => '2#037'), array('id' => 17, 'name' => 'Expiration time', 'tag' => '2#038'), array('id' => 18, 'name' => 'Instructions', 'tag' => '2#040'), array('id' => 19, 'name' => 'Action advised', 'tag' => '2#042'), array('id' => 20, 'name' => 'Reference service', 'tag' => '2#045'), array('id' => 21, 'name' => 'Reference date', 'tag' => '2#047'), array('id' => 22, 'name' => 'Reference number', 'tag' => '2#050'), array('id' => 23, 'name' => 'Date created', 'tag' => '2#055'), array('id' => 24, 'name' => 'Time created', 'tag' => '2#060'), array('id' => 25, 'name' => 'Digital creation date', 'tag' => '2#062'), array('id' => 26, 'name' => 'Digital creation time', 'tag' => '2#063'), array('id' => 27, 'name' => 'Originating program', 'tag' => '2#065'), array('id' => 28, 'name' => 'Program version', 'tag' => '2#070'), array('id' => 29, 'name' => 'Object cycle', 'tag' => '2#075'), array('id' => 30, 'name' => 'Author', 'tag' => '2#080'), array('id' => 31, 'name' => 'AuthorsPosition', 'tag' => '2#085'), array('id' => 32, 'name' => 'City', 'tag' => '2#090'), array('id' => 33, 'name' => 'Sublocation', 'tag' => '2#092'), array('id' => 34, 'name' => 'State/Province', 'tag' => '2#095'), array('id' => 35, 'name' => 'Country code', 'tag' => '2#100'), array('id' => 36, 'name' => 'Country', 'tag' => '2#101'), array('id' => 37, 'name' => 'Transmission reference', 'tag' => '2#103'), array('id' => 38, 'name' => 'Headline', 'tag' => '2#105'), array('id' => 39, 'name' => 'Credit', 'tag' => '2#110'), array('id' => 40, 'name' => 'Source', 'tag' => '2#115'), array('id' => 41, 'name' => 'Copyright notice', 'tag' => '2#116'), array('id' => 42, 'name' => 'Contact Information', 'tag' => '2#118'), array('id' => 43, 'name' => 'Description', 'tag' => '2#120'), array('id' => 44, 'name' => 'Description writer', 'tag' => '2#122'), array('id' => 45, 'name' => 'Image type', 'tag' => '2#130'), array('id' => 46, 'name' => 'Image orientation', 'tag' => '2#131'), array('id' => 47, 'name' => 'Language identifier', 'tag' => '2#135'), array('id' => 48, 'name' => 'AudioType', 'tag' => '2#150'), array('id' => 49, 'name' => 'AUdio sampling rate', 'tag' => '2#151'), array('id' => 50, 'name' => 'Audio sampling resolution', 'tag' => '2#152'), array('id' => 51, 'name' => 'Audio duration', 'tag' => '2#153'), array('id' => 52, 'name' => 'Audio outcue', 'tag' => '2#154'), array('id' => 53, 'name' => 'Job ID', 'tag' => '2#184'), array('id' => 54, 'name' => 'Master document ID', 'tag' => '2#185'), array('id' => 55, 'name' => 'Short document ID', 'tag' => '2#186'), array('id' => 56, 'name' => 'Unique document ID', 'tag' => '2#187'), array('id' => 57, 'name' => 'Owner ID', 'tag' => '2#188'), array('id' => 58, 'name' => 'Object preview file format', 'tag' => '2#200'), array('id' => 59, 'name' => 'Object preview file version', 'tag' => '2#201'), array('id' => 60, 'name' => 'Object preview data', 'tag' => '2#202'), array('id' => 61, 'name' => 'Prefs', 'tag' => '2#221'), array('id' => 62, 'name' => 'Classify state', 'tag' => '2#225'), array('id' => 63, 'name' => 'Similarity index', 'tag' => '2#228'), array('id' => 64, 'name' => 'Document notes', 'tag' => '2#230'), array('id' => 65, 'name' => 'Document history', 'tag' => '2#231'), array('id' => 66, 'name' => 'Exif camera info', 'tag' => '2#232'), array('id' => 67, 'name' => 'Catalog sets', 'tag' => '2#255') ); if (count($getAll) > 0) { foreach ($getAll as $tag) $this->listTags[$tag['id']] = $tag['tag']; } } /** * Returns the content of an IPTC tag. If $tag is not specified, returns all tags. * * @param string $tag Name of the IPTC tag presents in $this->listTags * @return string */ public function get($tag = null) { // If you specify a particular tag, it returns information for this tag if (!is_null($tag) && !empty($tag) && in_array($tag, $this->listTags)) { $size = getimagesize($this->file, $info); if (isset($info['APP13'][$tag])) { $iptc = iptcparse($info['APP13']); return $iptc[$tag][0]; } } else { // Otherwise, it returns the complete info $size = getimagesize($this->file, $info); if (isset($info['APP13'])) { return iptcparse($info['APP13']); } } } /** * Add an IPTC tag * * @param string $tag Name of the IPTC tag presents in $this->listTags * @param string $value IPTC tag value * @param bool $save If save the image with the settings or not * @return mixed */ public function add($tag, $value, $save = true) { // If tag is valid if (empty($tag) || empty($value) || !in_array($tag, $this->listTags)) return false; $tag = substr($tag, 2); $datas = $this->_transform_iptc($tag, $value); if ($save == true) $this->save($datas); else return $datas; } /** * Add severals IPTC tags * * @param array $array List of IPTC tags and values * @param bool $save If save the image with the settings or not * @return mixed */ public function addMultiple($array, $save = true) { // If tag is valid if (!is_array($array) || count($array) == 0) return false; $iptcdata = null; foreach ($array as $tag => $string) { if (in_array($tag, $this->listTags)) { $tag = substr($tag, 2); $iptcdata .= $this->_transform_iptc($tag, $string); } } if ($save == true) $this->save($iptcdata); else return $iptcdata; } /** * Save IPTC into image * * @param string $datas IPTC datas * @param string $newImageName New image name * @return void */ public function save($datas, $newImageName = '') { if (!empty($newImageName)) $imageName = $newImageName; else $imageName = $this->file; // Writing datas in the image $data_image = iptcembed($datas, $this->file); $fp = fopen($imageName, "wb"); fwrite($fp, $data_image); fclose($fp); } /** * Format the new IPTC text * * @param string $data IPTC datas * @param string $value IPTC tag value * @return string */ private function _transform_iptc($data, $value) { $length = strlen($value); $retval = chr(0x1C).chr(2).chr($data); if ($length < 0x8000) { $retval .= chr($length >> 8).chr($length& 0xFF); } else { $retval .= chr(0x80).chr(0x04). chr(($length >> 24)& 0xFF). chr(($length >> 16)& 0xFF). chr(($length >> 8)& 0xFF). chr($length& 0xFF); } return $retval.$value; } } // -- Examples $oIptc = new IptcManager(); // Returns all IPTC tags $oIptc->setFile('image_test.jpg')->get(); // Returns Title tag $oIptc->setFile('image_test.jpg')->get('2#005'); // Add a tag $oIptc->setFile('image_test.jpg')->add('2#025', 'My keywords'); $oIptc->get(); // Add severals IPTC tags $array = array( '2#080' => 'ShevAbam', '2#101' => 'France' ); $oIptc->setFile('image_test.jpg')->AddMultiple($array); $oIptc->get(); ?>
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 !
voici un code rapidement pondu, qui a l'air de fonctionner...
je l'ai écrit sous Lazarus, il doit être portable presque tel quel en Delphi.
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 unit Unit1; // copyright tourlourou 2011 // libre pour toute utilisation // proposé sans aucune garantie // merci notamment au site suivant pour la structure des données IPTC du segment APP13 : // http://search.cpan.org/~bettelli/Image-MetaData-JPEG-0.153/lib/Image/MetaData/JPEG/Structures.pod#Structure_of_a_Photoshop-style_APP13_segment {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtDlgs, StdCtrls; type { TForm1 } TForm1 = class(TForm) Button1: TButton; OpenPictureDialog1: TOpenPictureDialog; procedure Button1Click(Sender: TObject); private { private declarations } public { public declarations } end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } function ChercheAPP13IPTCTag(ATag: Byte; AStream: TMemoryStream): string; var Mot: Word; FinApp13, Card: Cardinal; APP13Found, SOSFound: Boolean; Octet: Byte; S: string; i: integer; begin Result:='non trouvé'; APP13Found:=False; SOSFound:=False; AStream.Seek(0, soFromBeginning); Mot:=Swap(AStream.ReadWord); if Mot<>$FFD8 then Exit; // pas JPEG repeat Mot:=Swap(AStream.ReadWord); case Mot of $FFED: APP13Found:=True; // on a trouvé le marqueur APP13 $FFDA: SOSFound:=True; // on a atteint le début l'image else begin Mot:=Swap(AStream.ReadWord); AStream.Seek(Mot-2, soFromCurrent); end; end; until APP13Found or SOSFound; if APP13Found then begin Mot:=Swap(AStream.ReadWord); // longueur APP13 FinApp13:=AStream.Position+Mot-2; // pour test ultérieur // titre APP13 S:=EmptyStr; repeat Octet:=AStream.ReadByte; if Octet>0 then S:=S+Chr(Octet); until Octet=0; // signature données Card:=SwapEndian(AStream.ReadDWord); if Card<>$3842494D then Exit; // = '8BIM' : signature IRB (Image Resource Block) // signature IPTC Mot:=Swap(AStream.ReadWord); if Mot<>$0404 then Exit; // bloc de données IPTC-NAA // champ 'Name' (souvent NULL) S:=EmptyStr; Octet:=AStream.ReadByte; // nombre de caractères de la chaîne (Pascal string) if Octet=0 then AStream.Seek(1, soFromCurrent) // car alignement pair (rempli avec 1 zéro) else begin for i:=1 to Octet do begin Octet:=AStream.ReadByte; S:=S+Chr(Octet); end; if Odd(Length(S)) then AStream.Seek(1, soFromCurrent) // car alignement pair (rempli avec 1 zéro) end; // longueur données qui suivent Card:=SwapEndian(AStream.ReadDWord); if AStream.Position+Card<>FinApp13 then Exit; // discordance données de longueur // parcours des tags while AStream.Position<FinApp13 do begin Octet:=AStream.ReadByte; if Octet<>$1C then Exit; // marqueur obligatoire Octet:=AStream.ReadByte; if Octet<>$02 then Exit; // on filtre les enregistrements d'application n°2 // qui correspondent aux champs IPTC décrivant le document Octet:=AStream.ReadByte; // tag Mot:=Swap(AStream.ReadWord); // longueur de la donnée i:=1 shl 15; // masque bit 15 if Mot and i = i then Exit; // champs de longueur > 32767 non gérés... if Octet=ATag then begin S:=EmptyStr; for i:=1 to Mot do begin Octet:=AStream.ReadByte; S:=S+Chr(Octet); end; Result:=S; Break; // sort du while end else AStream.Seek(Mot, soFromCurrent) end; end; end; procedure TForm1.Button1Click(Sender: TObject); var Flux: TMemoryStream; begin if OpenPictureDialog1.Execute then begin Flux:=TMemoryStream.Create; Flux.LoadFromFile(OpenPictureDialog1.FileName); ShowMessage(ChercheAPP13IPTCTag(55, Flux)); // Date Created : YYYYMMDD : 8 caractères ShowMessage(ChercheAPP13IPTCTag(60, Flux)); // Time Created : HHMMSS+/-HHMM : 11 caractères Flux.Free; end; end; end.
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 !
en D6 Identificateurs non déclarés
Readword, Readbyte, swapendian,
Mot:=AStream.ReadWord doit pouvoir se traduire en AStream.ReadBuffer(Mot, 2)
et Octet:=AStream.ReadByte en AStream.ReadBuffer(Octet, 1)
pour Card:=SwapEndian(aCard), il doit suffire de remplacer par Swap32 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 // inverse les octets d'un Cardinal function Swap32(C : Cardinal) : Cardinal; begin asm bswap EAX // C est passé dans EAX et bswap échange les octets 0123 -> 3210 mov Result, EAX end; end;
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 !
Il m'affiche invariablement "Non trouvé"
Voilà le source après correction
________
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 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtDlgs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; OpenPictureDialog1: TOpenPictureDialog; procedure Button1Click(Sender: TObject); private { Déclarations privées } public { Déclarations publiques } end; var Form1: TForm1; implementation {$R *.dfm} function Swap32(C : Cardinal) : Cardinal; begin asm bswap EAX // C est passé dans EAX et bswap échange les octets 0123 -> 3210 mov Result, EAX end; end; function ChercheAPP13IPTCTag(ATag: Byte; AStream: TMemoryStream): string; var Mot: Word; FinApp13, Card: Cardinal; APP13Found, SOSFound: Boolean; Octet: Byte; S: string; i: integer; begin Result:='non trouvé'; APP13Found:=False; SOSFound:=False; AStream.Seek(0, soFromBeginning); AStream.ReadBuffer(Mot, 2); if Mot<>$FFD8 then Exit; // pas JPEG repeat AStream.ReadBuffer(Mot, 2); case Mot of $FFED: APP13Found:=True; // on a trouvé le marqueur APP13 $FFDA: SOSFound:=True; // on a atteint le début l'image else begin AStream.ReadBuffer(Mot, 2); AStream.Seek(Mot-2, soFromCurrent); end; end; until APP13Found or SOSFound; if APP13Found then begin AStream.ReadBuffer(Mot, 2); // longueur APP13 FinApp13:=AStream.Position+Mot-2; // pour test ultérieur // titre APP13 S:=EmptyStr; repeat AStream.ReadBuffer(Octet, 1); if Octet>0 then S:=S+Chr(Octet); until Octet=0; // signature données Card:=Swap32(Mot); if Card<>$3842494D then Exit; // = '8BIM' : signature IRB (Image Resource Block) // signature IPTC AStream.ReadBuffer(Mot, 2); if Mot<>$0404 then Exit; // bloc de données IPTC-NAA // champ 'Name' (souvent NULL) S:=EmptyStr; AStream.ReadBuffer(Octet, 1); // nombre de caractères de la chaîne (Pascal string) if Octet=0 then AStream.Seek(1, soFromCurrent) // car alignement pair (rempli avec 1 zéro) else begin for i:=1 to Octet do begin AStream.ReadBuffer(Octet, 1); S:=S+Chr(Octet); end; if Odd(Length(S)) then AStream.Seek(1, soFromCurrent) // car alignement pair (rempli avec 1 zéro) end; // longueur données qui suivent Card:=Swap32(Mot); if AStream.Position+Card<>FinApp13 then Exit; // discordance données de longueur // parcours des tags while AStream.Position<FinApp13 do begin AStream.ReadBuffer(Octet, 1); if Octet<>$1C then Exit; // marqueur obligatoire AStream.ReadBuffer(Octet, 1); if Octet<>$02 then Exit; // on filtre les enregistrements d'application n°2 // qui correspondent aux champs IPTC décrivant le document AStream.ReadBuffer(Octet, 1); // tag AStream.ReadBuffer(Mot, 2); // longueur de la donnée i:=1 shl 15; // masque bit 15 if Mot and i = i then Exit; // champs de longueur > 32767 non gérés... if Octet=ATag then begin S:=EmptyStr; for i:=1 to Mot do begin AStream.ReadBuffer(Octet, 1); S:=S+Chr(Octet); end; Result:=S; Break; // sort du while end else AStream.Seek(Mot, soFromCurrent) end; end; end; procedure TForm1.Button1Click(Sender: TObject); var Flux: TMemoryStream; begin if OpenPictureDialog1.Execute then begin Flux:=TMemoryStream.Create; Flux.LoadFromFile(OpenPictureDialog1.FileName); ShowMessage(ChercheAPP13IPTCTag(55, Flux)); // Date Created : YYYYMMDD : 8 caractères ShowMessage(ChercheAPP13IPTCTag(60, Flux)); // Time Created : HHMMSS+/-HHMM : 11 caractères Flux.Free; end; end; end.
le code que j'ai posté fonctionne au moins sous Lazarus et sur la photo du site daylife.com que j'ai testée !
pour savoir quelle est la cause du non trouvé :
1) assure-toi que la photo que tu lui passes possède bien ces données avec un éditeur hexadécimal
2) vérifie grâce à un test la fonction Swap32 : si tu lui fournis $01020304, elle doit renvoyer $04030201, sinon elle est incorrecte (je ne l'ai pas vérifiée sous Delphi)
3) suis en débogage pas-à-pas pour voir où la fonction s’interrompt, ou si elle va jusqu'au bout
4) poste ta photo test que je la teste aussi
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 !
Ca ne marche pas...
Je ne peux même pas tester la fonction swap32 (au passage mon PC est en 64 bits), il m'affiche "violation d'adresse en réponse à
showmessage(floattostr(swap32($01020304)));
floattostr() sur un Longword, IntToStr() suffit !
Si tu as un problème avec l'assembleur, sache que cela peut s'écrire en pascal, faudrait faire l'effort de chercher sur le forum pour la classique conversion Little-Endian en Big-Endian
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 function SwapLongword(Value: Longword): Longword; {$IFDEF PUREPASCAL} type TMapLongword = array[0..3] of Byte; begin TMapLongword(Result)[0] := TMapLongword(Value)[3]; TMapLongword(Result)[1] := TMapLongword(Value)[2]; TMapLongword(Result)[2] := TMapLongword(Value)[1]; TMapLongword(Result)[3] := TMapLongword(Value)[0]; {$ELSE} asm BSWAP EAX {$ENDIF} end;
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité !
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Je suis désolé, je ne comprend pas, j'arrete...en attendant de trouver une procedure ou fonction toute faite qui marche
merci et a+
C'est gratuit et en français....
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager