J'essaie d'extraire la date / heure lorsqu'une image a été prise à partir du CR2 (format Canon pour les images brutes).
Je connais le Spécification CR2 , et je sais que je peux utiliser python struct module pour extraire des morceaux d'un tampon binaire. p>
brièvement, la spécification indique que dans la balise J'ai essayé d'obtenir cette balise en utilisant: p> mais je reçois p> éditer em> p> Merci beaucoup pour l'effort approfondi! Les réponses sont phénoménales et j'ai beaucoup appris sur la gestion des données binaires. P> p> 0x0132 / 306 code> Je peux trouver une chaîne de longueur 20 - la date et le temps. p>
3 Réponses :
0x0132 n'est pas le décalage, c'est le numéro de balise de la date. CR2 ou TIFF, respectivement, est un format à base de répertoires. Vous devez rechercher l'entrée donnée à votre étiquette (connue) que vous recherchez.
EDIT FORT>:
Ok, tout d'abord, vous devez lire si les données de fichier sont enregistrées à l'aide d'un format peu ou de Big-Endian. Les huit premiers octets spécifient l'en-tête et les deux premiers octets de cet en-tête spécifient l'endansion. Le module de struct de Python vous permet de gérer de petites et grosses données Endian en préfixant une chaîne de format avec ''. Ainsi, en supposant que la spécification de format indique que le premier répertoire de fichiers d'image commence À un décalage par rapport au début du fichier, le décalage étant spécifié dans les 4 derniers octets de l'en-tête. Donc, pour obtenir le décalage avec la première IFD, vous pouvez utiliser une ligne similaire à celle-ci: p> Vous pouvez maintenant aller de l'avant et lire le premier IFD. Vous trouverez le nombre d'entrées dans le répertoire au décalage spécifié dans le fichier, qui est deux octets large. Ainsi, vous alliez lire le nombre d'entrées dans la première IFD en utilisant: p> data code> est un tampon contenant votre image CR2, vous pouvez gérer l'endanse via P>
current_position = ifd_offset + 2
for field_offset in xrange(current_position, number_of_entries*12, 12):
field_tag = struct.unpack("{0}H".format(endian_flag), data[field_offset:field_offset+2])[0]
field_type = struct.unpack("{0}H".format(endian_flag), data[field_offset+2:field_offset+4])[0]
value_count = struct.unpack("{0}I".format(endian_flag), data[field_offset+4:field_offset+8])[0]
value_offset = struct.unpack("{0}I".format(endian_flag), data[field_offset+8:field_offset+12])[0]
if field_tag == 0x0132:
# You are now reading a field entry containing the date and time
assert field_type == 2 # Type 2 is ASCII
assert value_count == 20 # You would expect a string length of 20 here
date_time = struct.unpack("20s", data[value_offset:value_offset+20])
print date_time
Pouvez vous donner un exemple? Je suis à une perte complète ici ... merci!
Avez-vous pris en compte l'en-tête qui devrait (selon la spécification) précéder le bloc IFD dont vous parlez?
J'ai examiné la spécification et indique que le premier bloc IFD suit l'en-tête 16 octets. Donc, si nous lisons les octets 16 et 17 (à Offset 0x10 Hex), nous devrions obtenir le nombre d'entrées dans le premier bloc IFD. Ensuite, nous devons simplement rechercher chaque entrée jusqu'à la recherche d'un identifiant de tag correspondant qui (comme je l'ai lu) nous donne le décalage d'octets de votre chaîne de date / heure. P>
Cela fonctionne pour moi: P > sortie pour mon exemple de fichier est: p>
Merci @jon cage. J'ai bien peur de ne pas savoir comment faire ça. Comment puis-je savoir quel bloc précède?
Cela vaut la peine de faire la vérification de l'Endian selon la réponse de Jim pour une solution plus robuste, mais mon échantillon a fonctionné correctement sur une machine AMD Windows 7 :-)
Man c'est génial - merci!
C'est un peu vieux, je sais, mais si vous ne voulez pas lire les données vous-même, j'ai écrit une bibliothèque pour analyser les fichiers CR2 simplement appelés RAWPHOTO . C'est aussi sur PYPI . J'espère que c'est utile pour vous.