dimanche 5 février 2012
Créer un fichier image à partir du dataURL avec PHP
Publié par Infinite Loop, à 11 h 58
1 commentaire
Suite au billet d'hier qui expliquait comment enregistrer le contenu d'un canvas HTML5, j'ai mentionné qu'on pouvait utiliser un langage comme PHP pour récupérer le dataURL et en faire un fichier sur le disque. Je voulais apporter une précision à ce sujet, vous allez voir, c'est loin d'être compliqué.
On peut imaginer que la valeur du dataURL serait envoyée par Ajax à un script PHP. Comme on a vu que l'URL est composé du mime-type (PNG) et du contenu de l'image encodé en base64, on doit d'abord extraire cette portion et ensuite la décoder.
// donnée raccourcie pour faciliter la lectureUne fois en possession de la donnée binaire, on peut utiliser une combinaire de fopen/fwrite/fclose pour écrire le contenu dans un fichier physique.
$dataURL = 'data:image/png;base64,iVB[...]rkJggg==';
$parts = explode(',', $dataURL);
$data = $parts[1];
$data = base64_decode($data);
$fp = fopen('exemple-1.png', 'w');Ou encore plus simple, en une seule ligne.
fwrite($fp, $data);
fclose($fp);
file_put_contents('exemple-2.png', $data);Ça devient un peu plus compliqué si on veut apporter des modifications à l'image avant de l'enregistrer. Par exemple, l'extension GD (qui est souvent installée par défaut sur les serveurs) permet de récupérer la source du contenu sous forme de texte.
L'image du canvas est transparente. Il faudra donc appliquer la valeur true à imagesavealpha, sans quoi la couleur de fond deviendra noire par défaut. Ensuite, on appliquera les altérations voulues (par exemple combiner deux images, apposer le logo de la compagnie, etc) et on enregistrera le résultat à l'aide de la fonction imagepng().
À noter que si vous avez appliqué une couleur de fond en CSS à la balise canvas (comme j'ai fait dans l'exemple de spirale), cette couleur ne fait pas parti de l'image lors de l'enregistrement. Vous devrez soit l'appliquer directement au canvas, soit ajouter la couleur de fond de votre choix pour remplacer la transparence par GD.
$img = imagecreatefromstring($data);Dans les deux premiers exemples, la poids des images enregistrées était de 19 kb. Avec les paramètres par défaut de GD, l'enregistrement de la même image produisait un fichier de 23 kb. Si vous avez un souçi d'optimisation de l'espace de stockage, ajustez le paramètre de compression de la fonction imagepng() car le poids varie énormément.
if($img !== false){
// pour la transparence
imagesavealpha($img, true);
// modifications ici
imagepng($img, 'exemple-3.png');
imagedestroy($img);
}
else{
echo 'Erreur';
}
// par défaut
imagepng($img, 'exemple-3.png'); // 19 kb
// compression maximale
imagepng($img, 'exemple-3.png', 9, PNG_NO_FILTER); // 16.5 kb
// aucune compression
imagepng($img, 'exemple-3.png', 0, PNG_NO_FILTER); // 978 kb !
Bon, j'aurais du lire le post du jour avant de commenter celui de la veille (mais j'ai du retard dans mes lectures).
Donc rectification : il est possible de le sauvegarder via php :-)
Merci de m'éviter de faire la recherche (comme quoi, parfois, lire avec un temps de retard, me fait gagner du temps... lol)