Watermark d'images : script PHP simple, multi-formats, et multi-tailles

09.06.2012

Sur internet, on trouve très facilement des scripts PHP simples de watermarking (signature) d'images à la volée, à partir d'un texte, ou d'une autre image (comme celui-ci, ou celui-là), mais la plupart du temps, ceux-ci ne sont faits que pour travailler sur des images de même taille, et en moyenne uniquement des images au format JPEG.

Le problème, c'est quand on est susceptible d'utiliser différents formats pour l'image à signer (JPEG, PNG, GIF...), et des tailles variables, résultant un watermark mal positionné, voire trop petit, ou dépassant du cadre...

Voici donc un exemple de script simple, multi-formats et multi-tailles, que j'ai réalisé à partir de différents modèles :

PHP:

<?php
 
    $source $_REQUEST["source"] ;
 
    // Chargement de l'image
    $type strtolower(substr(strrchr($source,"."),1))    ;
    if($type == "jpeg"$type "jpg" ;
    switch($type){
        case "bmp" $image imagecreatefromwbmp($source) ; break ;
        case "gif" $image imagecreatefromgif($source) ; break ;
        case "jpg" $image imagecreatefromjpeg($source) ; break ;
        case "png" $image imagecreatefrompng($source) ; break ;
    }
 
    // Définition de sa taille
    list($width$height) = getimagesize($source) ;
 
    // Chargement du watermark, en fonction de la taille : 480, 640, 800, 1024
    if($width >= 480 && $width 640$watermark imagecreatefrompng("watermark_480.png") ;
    else if($width >= 640 && $width 800$watermark imagecreatefrompng("watermark_640.png") ;
    else if($width >= 800 && $width 1024$watermark imagecreatefrompng("watermark_800.png") ;
    else if($width >= 1024$watermark imagecreatefrompng("watermark_1024.png") ;
    else $watermark imagecreatefrompng("transparent.png") ;
 
    // Définition de sa taille
    $w_width imagesx($watermark) ;
    $w_height imagesy($watermark) ;
 
    // Calcul des coordonnées du watermark, pour son application sur l'image
    $dest_x = ($width $w_width) / ;
//    $dest_y = ($height - $w_height) / 2 ; // centré
    $dest_y $height $w_height round(* ($height $w_height)) ; // bas, relève si image beaucoup plus haute que watermark
 
    // Application du watermark sur l'image
    imagecopy($image$watermark$dest_x$dest_y00$w_width$w_height) ;
 
    // Affichage et libération de la mémoire
    switch($type){
        case "bmp" header("Content-type: image/wbmp") ; imagewbmp($imagenull) ; break ;
        case "gif" header("Content-type: image/gif") ; imagegif($imagenull) ; break ;
        case "jpg" header("Content-type: image/jpeg") ; imagejpeg($imagenull100) ; break ;
        case "png" header("Content-type: image/png") ; imagepng($imagenull0) ; break ;
    }
    imagedestroy($image) ;
    imagedestroy($watermark) ;
    exit ;
 
?>

Code à coller dans un fichier .php, nommé comme il vous plaira, et à appeler dans la balise HTML <img> habituelle, en précisant le lien relatif de l'image à signer dans l'argument source.

Exemple :

<img src="watermark.php?source=mes_images/mon_image.jpg" border="0" alt="" />

...

Le script détecte le format de l'image en entrée, et ressort une image au même format, en sortie. Le même format en sortie n'est pas obligatoire (on peut ne sortir qu'une image au format PNG), mais c'est plus propre si on appelle le script avec le nom d'une image dans un format scpécifique (si on masque le script et qu'on l'appelle avec, par exemple, watermark_mon_image.bmp, ça renvoie une image au format BMP).

La signature étant basée sur une image PNG (le texte c'est pratique, mais moins design), pour adapter sa taille, à celle de l'image à signer, on crée plusieurs signatures (placées dans le même dossier que le script, par défaut), à différentes tailles, et on charge l'une d'entre-elles, en fonction de la taille de l'image à signer, tout simplement (à priori, un redimensionnement internet serait possible, mais engendrerait un traitement supplémentaire pour ne pas perdre la transparence).

Pour n'utiliser qu'une seule signature (d'une seule taille), il suffit de replacement les lignes 18 à 23, par :

PHP:

$watermark imagecreatefrompng("watermark.png") ;


Pour que ce type de watermarking trouve toute son efficacité, il convient de ne pas le placer au même endroit que les images à signer, de protéger le dossier de celles-ci par un fichier .htaccess (deny from all), et de masquer le script grâce à la fonction d'URL Rewriting (à condition que votre serveur le permette).

Exemple, avec la ligne suivante :

RewriteRule    ^voir/mes_images/([^/]+)\.([^/]+)$    watermark.php?source=mes_images/$1.$2

On charge les images signées, de la manière suivante :

<img src="voir/mes_images/mon_image.jpg" border="0" alt="" />


Le script fonctionne aussi avec des images hébergées sur un serveur externe.