IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Python Discussion :

Trouver les "exifs" des fichiers image avec exiftool


Sujet :

Contribuez Python

  1. #1
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut Trouver les "exifs" des fichiers image avec exiftool
    Bonjour,

    Je rappelle que les fichiers "jpg" (et beaucoup d'autres!) ont souvent des informations supplémentaires, appelées "exifs", en plus de l'image elle-même, comme celles sur la prise de vue ou sur le réglage de l'appareil photo utilisé.

    Comme je fais des photos depuis longtemps, je voulais trouver les informations de type "exif" de mes fichiers jpg. J'ai essayé pas mal de solutions avec Python (voir dans pypi), mais la solution la plus puissante que j'ai trouvée est l'exécutable "exiftool" de Phil Harvey: https://www.sno.phy.queensu.ca/~phil/exiftool/.

    C'est un exécutable prévu pour la console (donc sans Python), et il est multiplateforme. Il reconnait de très nombreux formats de fichiers, et il permet le plus souvent la lecture / écriture / création d'exifs.

    Je ne me suis intéressé qu'à la version pour Windows (=> exiftool.exe). L'exécutable n'a pas besoin d'être installé: il suffit de désarchiver le zip.

    Et comme je voulais l'utiliser à partir de Python, je donne ici le code que j'utilise. L'avantage d'utiliser Python, c'est qu'on peut chercher parmi toutes les photos qu'on a (env. 15.000 chez moi), celles qui correspondent à un critère donné (ex: objectif utilisé), ou même à faire des statistiques (ex: % des photos par marque d'appareils photo utilisés). Et pour que ce soit plus pratique à utiliser, rien n'empêche d'intégrer cette recherche dans un programme graphique.

    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
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    # Python 3.7
     
    import os
    from collections import OrderedDict
    from subprocess import Popen, PIPE, STDOUT
     
    ##############################################################################
    class Cherchexif:
        """Trouve l'exif d'un fichier image par appel de l'exécutable "exiftool"
           Retourne un dictionnaire ordonné => cle:valeur
           Si erreur (pas d'exif, ...), retourne un dictionnaire vide
        """
     
        #=========================================================================
        def __init__(self, progexec="exiftool.exe", codout="cp850", codefic="UTF8"):
            self.progexec = progexec # adresse de l'exécutable à appeler
            self.codout = codout # encodage des sorties console de exiftool
            self.codefic = codefic # encodage des noms de fichier de l'OS
     
        #=========================================================================
        def __call__(self, fichier):        
            lignes = []
            if os.path.exists(fichier):
                options = ["-charset", "filename={}".format(self.codefic)]        
                commande = [self.progexec] + options + [fichier]
                with Popen(args=commande, stdout=PIPE, stderr=STDOUT) as process:
                    while process.poll() is None:
                        ligne = str(process.stdout.readline(), self.codout).strip()
                        if ligne!="":
                            cle, val = ligne.split(sep=':', maxsplit=1)
                            cle = cle.rstrip(" \t\n\r\x00")
                            val = val.rstrip(" \t\n\r\x00")
                            lignes.append([cle, val])
                    if process.poll()!=0: # => fichier sans exif
                        lignes = [] # retournera un dictionnaire vide
            dicoexif = OrderedDict(lignes) # convertit en dictionnaire ordonné  
            return dicoexif
    Utilisation pour trouver les exifs d'un fichier:

    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
     
    if __name__ == "__main__":
     
        # adresse de l'exécutable à appeler
        progexec = r"chemin\vers\exiftool.exe"
     
        # adresse du fichier dont on cherche les infos "exif"
        fichier = r"chemin\vers\le\fichier\maphoto.jpg"
     
        # recherche des infos "exif"
        cherchexif = Cherchexif(progexec)
        dicoexif = cherchexif(fichier)
     
        # affichage du résultat
        if dicoexif:
            for cle in dicoexif:
                print(cle, "===>", dicoexif[cle])
        else:
            print("Pas d'exif ou fichier non trouvé") # retour d'un dict. vide
    On trouve de très nombreux résultats, y compris les informations spécifiques à la marque et à l'appareil photo, comme l'objectif utilisé, ou comme le nombre de déclenchements faits sur cet appareil ("shutter count").

    Je ne suis pas allé plus loin avec exiftool, mais en lisant sa doc, on voit qu'il y a vraiment beaucoup de possibilités. Par exemple, quand on veut supprimer les exifs d'une photo avant de la publier sur le web, on peut faire en console:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chemin\vers\exiftool.exe -all= chemin\vers\maphoto.jpg
    Il ne restera alors comme exif que les quelques infos de base comme les dates du fichier et les dimensions de la photo.

    Bon amusement!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  2. #2
    Membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Septembre 2013
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2013
    Messages : 91
    Points : 52
    Points
    52
    Par défaut problème avec la ligne "ligne = str(process.stdout.readline(), self.codout).strip()"
    Bonjour,
    Je ne connais pas du tout la manipulation d'un sous processus en python.
    J'ai utilisé votre code pour extraire les données exif d'une photo jpeg prise avec un pentax K1.

    J'ai le message suivant au niveau de la ligne ligne = str(process.stdout.readline(), self.codout).strip() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Traceback (most recent call last):
      File "D:\Patrice\Python\Exif photos\ChercheExif.py", line 54, in <module>
        dicoexif = cherchexif(fichier)
      File "D:\Patrice\Python\Exif photos\ChercheExif.py", line 30, in __call__
        ligne = str(process.stdout.readlines(), self.codout).strip()
    TypeError: decoding to str: need a bytes-like object, list found
    La variable ligne n'est pas vide, elle comporte à l'écran de l'idle plus de 500 lignes avec les données que je recherche, la moitié possédant des ":", l'autre moitié des "===>"

    Merci de m'aider à résoudre le problème?

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 277
    Points : 36 762
    Points
    36 762
    Par défaut
    Salut,
    Citation Envoyé par Cemalatowilo Voir le message
    Merci de m'aider à résoudre le problème?
    Si la ligne 30 du code de départ contient .readline(), celle de celui qui plante contient .readlines()... qui effectivement retourne la liste des lignes du fichier.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Réponses: 0
    Dernier message: 03/05/2010, 17h43
  2. Manipuler des fichiers images avec du .NET
    Par zooffy dans le forum ASP.NET
    Réponses: 20
    Dernier message: 15/10/2009, 11h44
  3. Réponses: 4
    Dernier message: 09/01/2009, 23h07
  4. Recherche d'un SGBG pour la gestion des fichiers images !
    Par PandaConstantin01 dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 04/09/2006, 13h53
  5. Les logiciels pour compiler des fichiers HTML en fichiers d’
    Par Edoxituz dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 23/02/2006, 17h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo