Quel photographe n’a jamais rêvé d’indiquer automatiquement sur ses photographies les informations EXIF de prise de vue ? Est-ce réalisable avec Photoshop ?
Premier article d’une série dédié à la programmation de Photoshop, que je désirais faire depuis un certain temps déjà, je vous propose de voir comment très « simplement » réaliser ce genre d’opération, notamment avec quelques astuces pour insérer les informations EXIF et même quelques champs IPTC sur vos photos 😉
(code compatible avec Photoshop CS2 et CS3 – à voir pour la compatibilité avec les versions ultérieures !)
À CONSULTER ÉGALEMENT : Pour en savoir plus sur la retouche photo…
Préambule : la programmation de Photoshop
Le fonctionnement de ce que l’on appelle les scripts (aussi appelés « actions », bien qu’ils figurent dans la palette nommée « Scripts ») est connu de tout utilisateur un tant soit peu habitué à Photoshop. Ils permettent de mémoriser une succession d’actions réalisées par l’utilisateur et de les réexécuter avec un certain nombre de possibilités (je vous réfère à cet article pour en savoir un peu plus à ce propos…)
Toutefois, ces scripts (qui s’apparentent aux macros que l’on peut enregistrer sous Excel ou Word) ont des limites, et ne permettent par exemple pas d’exécuter des actions conditionnelles, paramétrables, ou encore de récupérer des informations relatives à une composition ou une photographie. Et c’est là qu’intervient une autre fonctionnalité méconnue de Photoshop : la programmation des scripts.
Photoshop permet l’exécution de divers types de scripts :
- L’AppleScript, propre aux plate-formes Mac et implémenté au niveau du système d’exploitation (extension .scpt, facultative)
- Le VBScript, propre aux plate-formes PC sous Windows (fichiers texte avec extension .vbs)
- Le Javascript, compatible avec les deux plate-formes (fichiers texte avec extension .jsx ou .js)
Nous allons donc nous intéresser à créer de petits scripts JSX, du fait de leur compatibilité avec les deux plate-formes connues utilisées avec Photoshop. On peut utiliser ces scripts en passant par le menu Fichier / Script, soit en les chargeant manuellement en cliquant sur le menu Parcourir… et en allant chercher notre fichier .jsx, ce qui aura pour effet de l’exécuter immédiatement, soit – ce qui nous intéresse le plus – en copiant nos scripts .jsx dans le sous-répertoire \Paramètres prédéfinis\Scripts du répertoire d’installation de Photoshop, ce qui permettra de les utiliser directement dans des actions enregistrables !
Pour en savoir plus sur la programmation de Photoshop, je vous invite à vous rendre dans le sous-répertoire
\Guide des scriptsdu répertoire d’installation de Photoshop ^_^ (attention, un peu lourd à digérer au début, et demande un minimum de notions en programmation !)
Insérer EXIFs et IPTC dans nos photographies : méthodologie
Comme il n’est pas question ici de faire un cours de programmation, ni de vous prémâcher le travail, je vous propose de voir comment très simplement, nous allons pouvoir créer des scripts qui seront réutilisables dans Photoshop ! Le principe est donc le suivant :
- créer des scripts JSX qui se contenteront d’ajouter un calque texte contenant les informations désirées, non mises en forme
- utiliser ces scripts JSX dans des actions Photoshop enregistrées dans des macros, afin de pouvoir travailler avec le calque texte généré
- éventuellement, automatiser intégralement le processus, par exemple avec le processeur de scripts (voir cet article pour plus d’informations à ce propos !)
La base de nos documents JSX sera la suivante (je ne vais pas faire de cours de programmation, aussi les commentaires dans le code vous aideront à en comprendre la signification !) :
//////////////////////////////////////////////////////////////////////// ///// Base de script pour insertion de calques de texte ///// ///// © Cédric Girard - https://blog.aube-nature.com //////////////////////////////////////////////////////////////////////// #target photoshop // Script dédié à Photoshop app.bringToFront(); // On place Photoshop au premier plan displayDialogs = DialogModes.NO; // Désactivation des boîtes de dialogue // Sauvegarde des unités de mesure en cours, et passage en pixels par défaut var oRulerUnits = preferences.rulerUnits; var oTypeUnits = preferences.typeUnits; preferences.rulerUnits = Units.PIXELS; preferences.typeUnits = TypeUnits.PIXELS; try { var DocActif = activeDocument; // Document actif (image ouverte au premier plan) // Définition d'une variable définissant une couleur blanche, que nous utiliseront plus loin var colorBlanc = new SolidColor(); colorBlanc.rgb.red = 255; colorBlanc.rgb.blue = 255; colorBlanc.rgb.green = 255; // On crée un nouveau calque texte var oLayer = DocActif.artLayers.add(); oLayer.kind = LayerKind.TEXT; // Type de calque = calque de texte oLayer.name = "Nom du calque"; // Nom du calque var oTextItem = oLayer.textItem; // On définit une variable qui permettra de simplifier les accès au calque de texte créé oTextItem.font = "Century gothic"; // Définition de la police oTextItem.size = 14; // Définition de la taille de police oTextItem.color = colorBlanc; // Définition de la couleur du texte ///////////////////////////////////////////////////////////////////// ////////// ZONE MODIFIABLE (insertion de votre texte) ///////////////////////////////////////////////////////////////////// ////////// // Pour créer un retour à la ligne (parfois utile) insérer "\u000D" oTextItem.contents = "ici le texte à ajouter"; // Contenu du texte ////////// ////////// ///////////////////////////////////////////////////////////////////// // Centrage du calque de texte au milieu de la compo (par défaut) var LargeurTexte = (oLayer.bounds[2] - oLayer.bounds[0]); // Largeur du calque de texte var HauteurTexte = (oLayer.bounds[3] - oLayer.bounds[1]); // hauteur du calque de texte oTextItem.position = [(DocActif.width-LargeurTexte) / 2, (DocActif.height-HauteurTexte) / 2]; } catch(oErreur) { // Une erreur est survenue... alert( "Une erreur est survenue : " + oErreur.description) } // Remise en place des unités de mesure initiales preferences.rulerUnits = oRulerUnits; preferences.typeUnits = oTypeUnits; ////////// FIN DU SCRIPT //////////////////////////////////////////// Langage du code : JavaScript (javascript) Vous remarquerez la zone entourée de commentaires au milieu du script, c’est là que nous allons donc insérer notre texte ! Passons maintenant aux choses sérieuses… Les métadonnées se trouvent dans l’objet info de chaque objet document ouvert dans Photoshop. C’est ce que nous allons utiliser pour lire les champs EXIF et IPTC qui nous intéressent !
Insérer les données EXIFs
La lecture des données EXIF dans une image n’est pas une chose simple, que cela soit en Javascript ou autrement d’ailleurs. Néanmoins, Photoshop et son modèle objet permettent un accès relativement aisé à ces données, moyennant un peu de tâtonnement, mais une fois la solution trouvée, tout devient simple… ou presque 😀
En fait, tout serait simple si Adobe avait conservé, d’une version à l’autre de son outil phare, la même organisation des informations (notamment EXIF) ! Mais ce n’est pas le cas, aussi je vous proposerai, uniquement pour les champs EXIF, deux codes légèrement différents selon que vous utilisez Photoshop CS2 ou CS3 (je n’ai pas testé avec les versions précédentes, ne disposant que de CS2 et d’une version éval de CS3 !)
Avec Photoshop CS2 :
Je suis arrivé à mes fins en affichant l’intégralité des données EXIF dans une boîte de dialogue (instruction alert en javascript), dans le code ci-dessus avec DocActif.info.exif (en javascript, les tableaux sont affichables et accessibles comme une simple chaîne de caractères…) ; chaque information est stockée après un code sur 6 chiffres, ainsi (à titre d’exemple) la sensibilité utilisée est stockée après le code 134855. De simples fonctions de chaînes de caractères permettent donc d’en récupérer les valeurs 😉
Le code pour récupérer les EXIF est donc le suivant (ici par exemple pour récupérer l’ouverture utilisée) :
// Lecture des informations EXIF contenues dans l'image var header = " 133434 "; for(n = 0; n < DocActif.info.exif.length; n = n + 1 ) { var oTemp = DocActif.info.exif[n][1];</code> // Ouverture focale if(oTemp.indexOf(" 133437")!=-1) { var exifOuverture = oTemp.substr(header.length,oTemp.length-header.length); } } oTextItem.contents = exifOuverture; // On écrit l'ouverture dans notre calque de texte Langage du code : JavaScript (javascript) Ceci étant dit, il nous est désormais très simple d’aller lire les informations EXIF, qui par chance sont pré-formattées par Photoshop (pour avoir programmé un outil de lecture de ces données en Visual Basic.Net, je peux vous dire qu’à l’état brut dans l’image, c’est autre chose !!!) ; voici une liste non exhaustive de « marqueurs » intéressants :
- 133434 : Durée d’exposition (formattée sous la forme « 1/30 sec »)
- 136867 : Date de prise de vue (nécessitant une manipulation pour obtenir un format utilisable)
- 100272 : Modèle d’appareil photo utilisé (format « constructeur », par ex. « Canon EOS 5D »)
- 133437 : Ouverture (formattée sous la forme « f/4.5 »)
- 134855 : Sensibilité ISO
- 137386 : longueur focale (formattée sous la forme « 100.0 mm »)
- 137380 : correction d’exposition (formattée sous la forme « 0.00 » ou « -0.33 »)
Partant de ces éléments, je vous laisse le soin d’arranger à votre goût le formattage de ces informations, en reportant les codes ci-dessus dans le morceau de code présenté précédemment, sur la ligne if(oTemp.indexOf(" 133437")!=-1) (attention à bien respecter l’espace juste avant le code !). Je vous renvoie (pour ceux qui ne maîtrisent pas le Javascript et de manière plus générale la programmation) deux chapitres plus loin, pour télécharger directement les scripts prêts à l’emploi !
Avec Photoshop CS3 :
Quelle ne fut pas ma déconvenue lorsqu’un utilisateur m’indiqua à la publication de cet article, que CS3 ne gérait pas de la même manière les champs EXIF ! Il a donc fallu modifier le code en conséquence (j’aurais voulu utiliser la propriété Application.Version du modèle objet de Photoshop, censée retourner le n° de version de Photoshop, de manière à n’avoir au final qu’un seul et unique script mais cela ne fonctionne pas à priori…) et ajouter deux fonctions bien utiles, que m’a indiqué Patrick (alias Mainsoft du forum Chassimages), pour gérer plus simplement tout cela (code à insérer juste en-dessous de la ligne var DocActif = activeDocument;, juste avant la déclaration des variables utiles) :
var exifData = DocActif.info.exif.toString(); var exifArray = explodeArray(exifData,","); //////////////////////////////////////////////////////////////////////// // Function: explodeArray (credit: Joe Colson) // Usage: creates array of strings from argument item using delimiter as index // Input: string item, delimiter // Return: tempArray, an array of strings from string argument item //////////////////////////////////////////////////////////////////////// function explodeArray(item, delimiter) { tempArray = new Array(); var Count = 0; var tempString = new String(item); while (tempString.indexOf(delimiter) &gt; -1) { tempArray[Count] = tempString.substr(0,tempString.indexOf(delimiter)) tempString = tempString.substr(tempString.indexOf(delimiter) + 1, tempString.length - tempString.indexOf(delimiter) + 1) Count = Count + 1 } return tempArray; } // End explodeArray //////////////////////////////////////////////////////////////////////// // Function: getArrayString (credit: Joe Colson) // Usage: searches for string searchString // Input: inputArray, searchString // Return: string PREVIOUS "searchString" in array inputArray // Modif Cédric GIRARD (recherche par code et non par appelation de champs) // cause versions multilingues de Photoshop //////////////////////////////////////////////////////////////////////// function getArrayString(inputArray,searchString) { for(n = 0; n < inputArray.length; n = n + 1 ) { if(inputArray[n] == searchString) { return inputArray[n - 1]; } } } // End getArrayString Langage du code : JavaScript (javascript) Le code de récupération des valeurs de champs EXIF est du coup plus « simple » qu’avec CS2, grâce à ces fonctions bien utiles :
var exifOuverture = getArrayString(exifArray, "33437"); Langage du code : JavaScript (javascript) Ici, le code recherché change légèrement car amputé de 100000 ; ainsi, les codes à utiliser sont les suivants ::
- 33434 : Durée d’exposition (formattée sous la forme « 1/30 sec »)
- 36867 : Date de prise de vue (nécessitant une manipulation pour obtenir un format utilisable)
- 272 : Modèle d’appareil photo utilisé (format « constructeur », par ex. « Canon EOS 5D »)
- 33437 : Ouverture (formattée sous la forme « f/4.5 »)
- 34855 : Sensibilité ISO
- 37386 : longueur focale (formattée sous la forme « 100.0 mm »)
- 37380 : correction d’exposition (formattée sous la forme « 0.00 » ou « -0.33 »)
On notera la « dangerosité » du code permettant de récupérer le modèle d’appareil photo… même s’il est peu probable d’avoir cette valeur quelque part dans l’un des champs ! L’essentiel étant que cela fonctionne ^_^
Insérer les champs IPTC
La gestion des champs IPTC est beaucoup plus simple car identique quelle que soit la version de Photoshop, et puisqu’il s’agit de propriétés directes de l’objet info du document que l’on utilise. Néanmoins, l’accès à ces informations est limité puisque seules certaines données IPTC (à priori celles disponibles dans la première version de la norme) sont accessible. Dans notre maquette de script, cela donnerait donc très simplement :
oTextItem.contents = DocActif.info.title; // On écrit le titre de la zone IPTC "Etat" dans notre calque de texte Langage du code : JavaScript (javascript) Les principaux champs accessibles sont ici (liste non exhaustive ; remplacer « title » dans le code ci-dessus) :
- title : champs « Titre » de la zone « État » (sous Photoshop ou Bridge, appelée aussi « Titre du document »)
- headline : champs « Titre » de la zone « Contenu » (sous Photoshop ou Bridge, appelée « Titre » tout court)
- caption : champs « Description » sous Photoshop (sous Lightroom, correspond à la zone « Contenu / Légende »)
- instructions : champs « Instructions » (qui contient généralement les informations de copyright, par ex. « © Cédric GIRARD »)
En complément, je vous indique aussi comment récupérer le nom du fichier, ce qui peut parfois être utile :
oTextItem.contents = DocActif.name; // On écrit le nom du document actif (ex : "_MG_1234.JPG") Langage du code : JavaScript (javascript) Je me limiterai à ces 5 champs dans le cadre de cet article, et je vous invite au chapitre qui suit pour télécharger directement les scripts JSX qui les concernent !
Les scripts JSX qui serviront à créer vos propres actions
Voici donc une petite liste de scripts JSX à copier dans le sous-répertoire \Paramètres prédéfinis\Scripts du répertoire d’installation de votre version de Photoshop 😉 ; pour les télécharger, cliquez ici pour CS2 et ici pour CS3 (fichier ZIP à décompacter dans le répertoire cité précédemment).
Au programme :
- Insertion EXIF complet avec modele APN.jsx : insertion d’un calque texte avec le modèle d’appareil utilisé, et sur la ligne suivante les EXIF (focale, ouverture, vitesse, ISO, et le cas échéant correction d’exposition)
- Insertion EXIF complet.jsx : idem précédemment, mais sans la première ligne comportant le modèle d’appareil photonumérique utilisé
- Insertion EXIF date courte.jsx : insertion d’un calque texte avec la date de prise de vue EXIF (format « 15/02/2008 »)
- Insertion EXIF date longue.jsx : insertion d’un calque texte avec la date de prise de vue EXIF (format « 15 février 2008 »), avec gestion du « 1er » du mois 😉
- Insertion EXIF modele APN.jsx : insertion d’un calque texte avec le modèle d’appareil utilisé
- Insertion IPTC Description.jsx : insertion d’un calque texte avec la description IPTC de l’image
- Insertion IPTC Instructions.jsx : insertion d’un calque texte avec les instructions IPTC de l’image (contenant souvent le copyright, faute de pouvoir accéder au champs spécifique à ce dernier !)
- Insertion IPTC Titre contenu.jsx : insertion d’un calque texte avec le titre de la zone IPTC « Contenu »
- Insertion IPTC Titre état.jsx : insertion d’un calque texte avec le titre de la zone IPTC « État » (sous Photoshop, équivaut à la zone « Titre du document »)
- Insertion nom du fichier.jsx : insertion du nom du fichier actif (par ex : « _MG_1234.JPG »)
Une fois les fichiers copiés au bon endroit, relancer Photoshop, puis vérifier leur bonne présence dans le menu Fichier / Scripts :

Et voici ce que l’on peut obtenir très rapidement grâce à ces scripts :

Conclusion
Voilà terminé le premier article consacré à la programmation de Photoshop, en espérant qu’il vous apportera des ressources complémentaires intéressantes pour vos propres utilisations concernant les EXIF et autres champs IPTC dans Photoshop ;-). J’ai volontairement limité le rendu final à son strict minimum, de manière à ce que vous puissiez vous-même mettre en pratique ce type de fonctionnalité !
Prochaines étapes : les manipulations conditionnelles d’images… Mais ceci est une autre histoire : à suivre !

