mercredi 11 septembre 2013

Afficher une photo dans le bon sens avec PHP dans une balise image

Voilà en voulant améliorer un cadre photo numérique pour mon piDashBoard (http://www.magdiblog.fr/), je me suis penché sur un problème tout bête : comment un logiciel comme picasa me présente les photos dans le bon sens alors que mon pauvre navigateur web ne le fait pas !!! 

La reponse est toute bête lorsque l'on prend une photo avec un appareil numérique celui-ci enregistre le sens dans lequel la photo est prise.
Ce sens est enregistré dans l'entête du fichier JPEG sous la variable : Orientation (http://fr.wikipedia.org/wiki/Exchangeable_image_file_format)
Voici une image explicative qui parle d'elle même : 


Bien maintenant rien de plus simple que faire un fichier PHP qui nous renvoie l'image dans le bon sens. 

Il faut d'abord installé la lib PHP GD pour manipuler les images
Dans mon cas le piDashBord tourne sur un RaspberryPi donc un serveur Apache qui est une base de débian modifiée (RaspBian)

       

           sudo apt-get install php5-gd

       
 

La lib GD est disponible sur l'ensemble des systèmes, avec une petite recherche google on trouve facilement comment l'installer en fonction du système

Puis le code pour tourner l'image dans le bon sens (il est commenté et donc facile à comprendre) :
maj -  2013 10 11 - correction d'un bug sous google chrome merci à petit loup qui me l'a signalé. En fait il faut surcharger output handler pour avoir un header strictement correct au protocole HTTP. Et oui chrome est strict
       

function output_handler($img) {
    header('Accept-Ranges:bytes');
 header('Content-type: image/png');
    header('Content-Length: ' . strlen($img));
    return $img;
}


// Fichier et degrés de rotation
function autoImageRotate($filename)
{
 //$filename = 'http://thor/gooBox/photo/IMG_9161.JPG';
 $degrees = 0;
 $largeurCadrePhoto = 800;
 
 //récupération des métas data du JPEG
 $exif_ifd0 = exif_read_data($filename);
 $size = getimagesize($filename);
 
 if (@array_key_exists('Orientation', $exif_ifd0)) {
  if($exif_ifd0['Orientation'] == '8') 
   $degrees = 90;
  if($exif_ifd0['Orientation'] == '3')
   $degrees = 180;
  if($exif_ifd0['Orientation'] == '6')
   $degrees = 270;
 }
  
 // Chargement
 $source = imagecreatefromjpeg($filename);
 
 //calcul de la réduction/agrandissement de l'image : 
 if($largeurCadrePhoto != $size[0])
 {
  $b = $largeurCadrePhoto/$size[0];
  $NouvelleHauteur = ($size[1] * $b);  
  $NouvelleImage = imagecreatetruecolor($largeurCadrePhoto , $NouvelleHauteur) or die ("Erreur");
  imagecopyresampled($NouvelleImage , $source, 0, 0, 0, 0, $largeurCadrePhoto, $NouvelleHauteur, $size[0],$size[1]);
  imagedestroy($source);
  $source = $NouvelleImage;
 }
 
 ob_start("output_handler");
 
 if ($degrees > 0) {
  $rotate = imagerotate($source, $degrees, 0);
  imagejpeg($rotate);
  imagedestroy($rotate);
  }
 else
  imagejpeg($source, null, 90);
 ob_end_flush();
 //libération de l'image
 imagedestroy($source);
}

 if(isset($_REQUEST['file'])){$file = $_REQUEST['file'];}else{$file = 'none';}
  
 autoImageRotate($file);
?>

       
 


Perso j'ai ajouté cette ligne dans ma page PHP pour avoir le fichier à contrôler en paramètre de mon get:

       

if(isset($_REQUEST['file'])){$file = $_REQUEST['file'];}else{$file = 'none';} autoImageRotate($file);

       
   


Et une pauvre balise IMG dont la source est la page photo.php avec le nom du fichier en paramètre

ET voilà la photo est présentée dans le bon sens

Aucun commentaire:

Enregistrer un commentaire