Modifier les métadonnées
Écrire et modifier les données IPTC d'une image n'est pas aussi facile que de les lire.
Nous allons utiliser une fonction assez difficile à manipuler : la fonction
iptcembed. Elle permet d'intégrer des données binaires IPTC dans une image JPEG.
Commençons par indiquer le chemin vers une image.
<?php
$chemin_image="dossier-images/image.jpg"; ?>
. Ceci étant fait nous pouvons passer aux choses sérieuses.
Il faut commencer par créer un tableau associatif qui associe au code de l'IPTC la valeur de l'IPTC.
Code : PHP1
2
3 | <?php
$iptc = array('2#105' => 'titre', '2#120' => 'Commentaire', '2#122' => 'Auteur');
?>
|
Tout à l'heure, le tableau contenant les IPTC se présentait sous la forme d'un tableau de tableau. Une matrice en quelque sorte. On associait à un code IPTC un tableau. Ici il faut renseigner les IPTC sous forme d'un tableau simple, qui, à un code IPTC, associe une chaîne de caractères.
Le but du jeu est alors de transformer ce tableau en quelque chose de compréhensible pour la fonction
iptcembed. Regardons la documentation de cette fonction.
mixed iptcembed ( string $iptcdata , string $jpeg_file_name [, int $spool ] )
La fonction prend deux paramètres plus un facultatif dont on se passera.
- $jpeg_file_name de type chaîne de caractères qui est le chemin vers l'image à modifier, mais ça je pense que vous l'aviez deviné tout seul.
- $iptcdata de type chaîne de caractères aussi mais qui est un peu particulier et qui requiert une attention particulière. Si j'ai dit que iptcembed est une fonction difficile à manipuler c'est à cause de ce paramètre.
L'idée est de transformer le tableau
$iptc en une chaîne de caractères compréhensible par
iptcembed.
Code : PHP1
2
3
4
5
6
7
8 | <?php
$iptcdata = NULL; #1
foreach($iptc as $tag => $string)#2
{
$tag = substr($tag, 2); #3
$iptcdata .= transformer_iptc($tag, $string); #4
}
?>
|
Dans l'ordre :
- On initialise $iptcdata pour la concaténation de la ligne 6 (sinon on concatène dans le vide à la première itération et ça plante).
- On parcourt tout le tableau $iptc qu'on a défini tout à l'heure.
- On supprime le 2# du code qui ne sert à rien pour la suite
- On concatène $iptcdata avec une chaîne de caractères retournée par la fonction transformer_iptc et qui permet de convertir une valeur IPTC (code + valeur) en chaîne iptcData.
N.B. : on aurait pu aussi définir
$iptc comme ceci :
<?php $iptc = array('005' => 'titre', '120' => 'Commentaire', '122' => 'Auteur'); ?>
et se passer de
<?php $tag = substr($tag, 2); ?>
.
La fonction
transformer_iptc est... spéciale. Et je ne vous l'expliquerai pas car j'en suis bien incapable. En gros, elle prend en paramètre un code iptc (ex : 105) et la valeur qui lui est associée et renvoie une chaîne de caractères qui contient les deux informations données sous une forme pas très lisible par un humain.
Je ne peux hélas pas vous en dire plus, mais si quelqu'un veut me faire part de ses connaissances, je serai ravi de compléter ce passage.
Conclusion : voilà la fonction et ne cherchez pas à la comprendre car ça fait mal à la tête.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | <?php
function transformer_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;
}
?>
|
Nous avons désormais une variable
$iptcdata complète et utilisable par
iptcembed. Du coup on va l'utiliser

.
Code : PHP1
2
3 | <?php
$donnees = iptcembed($iptcdata, $chemin_image);
?>
|
Hé mais ça n'a rien changé ?!?
En effet,
iptcembed n'écrit rien, elle renvoie une chaîne de caractères. La doc nous dit ceci :
Citation : Documentation PHPEn cas de succès [...] le fichier JPEG sera retourné sous la forme d'une chaîne de caractères.
Du coup il faut écrire soit-même le fichier. Pour ce faire on va :
- Ouvrir le fichier image en mode wb c'est-à-dire qu'on veut réécrire entièrement le fichier.
- Écrire le fichier image en mode binaire. On écrira la chaîne de caractères retournée par iptcembed.
Code : PHP1
2
3
4
5 | <?php
$fichier = fopen($chemin_image, "wb"); # Ouverture du fichier
fwrite($fichier, $donnees); # Écriture du fichier
fclose($fichier); # Fermeture du fichier
?>
|
Et voilà le travail ! Vous avez enregistré des IPTC dans une image.
Mais je n'ai pas fini. Si vous utilisez ce code vous allez avoir quelques déceptions.
Conserver les données
Prenons une image dont les IPTC sont :
- Titre > Coucher de soleil ;
- Auteur > Aravis ;
- Commentaire > Photo prise en haut du mont Blanc.
Mais vous vous dites :
"Hé mais c'est pas Aravis qui a pris la photo, c'est moi !". Qu'importe, vous faites la modification :
Code : PHP1
2
3
4 | <?php $iptc = array('2#122' => 'Moi');
# script d'écriture des iptc
?>
|
Le drame c'est que maintenant les champs titre et commentaire ont été effacés. Seul le champ auteur est rempli.
En fait, lorsqu'on écrit les IPTC, on efface toutes les données et on en écrit d'autres par dessus. Si on ne veut pas perdre celles qui étaient avant, il faut les retenir et les réécrire.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13 | <?php
GetImageSize ($f, $info);
if (isset ($info["APP13"]))
{
$iptc = iptcparse ($info["APP13"]);
# On transforme la "matrice" en tableau simple
foreach ($iptc as $tag => $valeur)
$iptc[$tag] = $valeur[0];
}
$iptc['2#122'] = 'Moi';
# Script d'écriture des iptc
|
Si on exécute ce code :
Ligne 5 :
$iptc est sous la forme "matrice".
$iptc = Array ( [2#105] => Array ( [0] => Coucher de soleil ) [2#120] => Array ( [0] => Photo prise en haut du mont Blanc ) [2#122] => Array ( [0] => Aravis ) ) .
Ligne 9 (à la fin du foreach) :
$iptc est sous la forme tableau simple.
$iptc = Array ( [2#105] => Coucher de soleil [2#120] => Photo prise en haut du mont Blanc [2#122] => Aravis ).
Ligne 10 : on a modifié l'auteur.
$iptc = Array ( [2#105] => Coucher de soleil [2#120] => Photo prise en haut du mont Blanc [2#122] => Moi ).
On peut alors écrire les IPTC sans perdre de données.
Le problème des mots-clés
Vous vous rappelez que je vous ai dit que les mots-clés pouvaient se présenter sous forme d'un tableau à plusieurs cases ?
Array ([2#025] => Array ( [0] => Mot clé 1 [1] => Mot clé 2 [2] => Mot clé 3 ))
Le problème c'est qu'avec des chaînes de caractères on ne pourra jamais refaire un tableau. On ne pourra pas dire dans une chaîne de caractères que
Mot-clé 1 est le premier mot clé,
Mot-clé 2 le deuxième, etc.
Quand on écrira des IPTC au mieux nous pourrons faire ceci :
Code : PHP1
2
3 | <?php
$iptc['2#025'] = 'Mot clé 1, Mot clé 2, Mot clé 3';
?>
|
Cette chaîne de caractères sera interprétée comme un seul mot-clé. Si vous récupérez plus tard cette donnée il faudra passer par la fonction
explode pour dissocier les mots-clés.
Il est à ma connaissance impossible d'enregistrer un tableau en php. Mais les informations sur le traitement des IPTC avec PHP manquent cruellement sur le net. Si jamais vous trouvez la solution vous savez où me trouver.
Ici s'achève l'écriture et la modification des IPTC en PHP.