2010-09-07 8 views
19

Si tomo una foto con una cámara, almacena la orientación/ángulo del aparato así que cuando veo la imagen en la PC con una buena aplicación, se muestra rotada automáticamente a 0.¿Cómo detectar el ángulo de toma de la foto, y rotar automáticamente para la visualización del sitio web como las aplicaciones de escritorio en la visualización?

Pero cuando cargo en un sitio web muestra el ángulo original, por lo que la imagen no se ve bien.

Cómo puedo detectar esto con PHP y rotar la imagen, y borrar esta bandera de ángulo de su metainformación.

Respuesta

23

Para hacerlo, debe leer la información EXIF ​​del archivo JPEG. Puede hacerlo con exif extensión de PHP o con PEL.

Básicamente, debe leer el indicador Orientation en el archivo. Aquí hay un ejemplo con la extensión PHP exif y WideImage para la manipulación de imágenes.

<?php 
$exif = exif_read_data($filename); 
$ort = $exif['Orientation']; 

$image = WideImage::load($filename); 

// GD doesn't support EXIF, so all information is removed. 
$image->exifOrient($ort)->saveToFile($filename); 

class WideImage_Operation_ExifOrient 
{ 
    /** 
    * Rotates and mirrors and image properly based on current orientation value 
    * 
    * @param WideImage_Image $img 
    * @param int $orientation 
    * @return WideImage_Image 
    */ 
    function execute($img, $orientation) 
    { 
    switch ($orientation) { 
     case 2: 
     return $img->mirror(); 
     break; 

     case 3: 
     return $img->rotate(180); 
     break; 

     case 4: 
     return $img->rotate(180)->mirror(); 
     break; 

     case 5: 
     return $img->rotate(90)->mirror(); 
     break; 

     case 6: 
     return $img->rotate(90); 
     break; 

     case 7: 
     return $img->rotate(-90)->mirror(); 
     break; 

     case 8: 
     return $img->rotate(-90); 
     break; 

     default: return $img->copy(); 
    } 
    } 
} 
+0

no estaba seguro de cómo utilizar la clase Andrew ha escrito, por lo que acaba de colocar la función dentro de mi controlador y pasó la variable de la imagen y su orientación. El trabajo es como un campeón. El único comentario es verificar que la imagen sea de tipo JPEG antes de llamar a exif_read_data, de lo contrario, php lanzará un error. – w00tw00t111

+0

Tenga en cuenta que este código requiere que instale la biblioteca de WideImage PHP. (Andrew lo menciona, pero sé que la mayoría de la gente solo va a copiar y pegar el código y luego no entender por qué no funciona para ellos.) Si no quiere instalar WideImage, hay otros ejemplos de cómo haz esto sin eso – orrd

+0

@ w00tw00t111 es un tipo de archivo que no es JPEG, ¿qué causa el siguiente error? 'Error fatal: excepción no detectada 'WideImage_UnknownImageOperationException' con el mensaje 'No se puede cargar' exifOrient 'operation.'' –

2

El indicador de rotación se almacena como parte de los datos EXIF ​​(consulte this article para obtener más información).

Deberá leer el indicador de rotación de los datos EXIF ​​en PHP y luego rotar la imagen para adaptarla. Hay una variedad de bibliotecas PHP EXIF, si tienes el servidor web configurado con la extensión instalada, podrás usar el PHP provided library.

Sugeriría rotar la imagen una vez al cargarla (por ejemplo, usando GD library - la mayoría de las instalaciones de PHP parecen venir con esto), para que no tenga que preocuparse por borrar los datos de rotación EXIF ​​(no estoy seguro cómo fácil, esto es con PHP, nunca lo he intentado).

14

Si lo que desea es utilizar GD y la extensión php EXIF ​​puede utilizar esto:

function _mirrorImage ($imgsrc) 
{ 
    $width = imagesx ($imgsrc); 
    $height = imagesy ($imgsrc); 

    $src_x = $width -1; 
    $src_y = 0; 
    $src_width = -$width; 
    $src_height = $height; 

    $imgdest = imagecreatetruecolor ($width, $height); 

    if (imagecopyresampled ($imgdest, $imgsrc, 0, 0, $src_x, $src_y, $width, $height, $src_width, $src_height)) 
    { 
     return $imgdest; 
    } 

    return $imgsrc; 
} 

function adjustPicOrientation($full_filename){   
    $exif = exif_read_data($full_filename); 
    if($exif && isset($exif['Orientation'])) { 
     $orientation = $exif['Orientation']; 
     if($orientation != 1){ 
      $img = imagecreatefromjpeg($full_filename); 

      $mirror = false; 
      $deg = 0; 

      switch ($orientation) { 
       case 2: 
       $mirror = true; 
       break; 
       case 3: 
       $deg = 180; 
       break; 
       case 4: 
       $deg = 180; 
       $mirror = true; 
       break; 
       case 5: 
       $deg = 270; 
       $mirror = true; 
       break; 
       case 6: 
       $deg = 270; 
       break; 
       case 7: 
       $deg = 90; 
       $mirror = true; 
       break; 
       case 8: 
       $deg = 90; 
       break; 
      } 
      if ($deg) $img = imagerotate($img, $deg, 0); 
      if ($mirror) $img = _mirrorImage($img); 
      $full_filename = str_replace('.jpg', "-O$orientation.jpg", $full_filename); 
      imagejpeg($img, $full_filename, 95); 
     } 
    } 
    return $full_filename; 
} 
11

he modificado ejemplo Chris' para añadir un cheque por la función Exif, quitar la creación de reflejo, y también para volver a escribir el archivo en el sistema de archivos usando el mismo nombre de archivo. De esta manera, se puede llamar a esta función justo después de llamar move_uploaded_file, así:

move_uploaded_file($uploadedFile, $destinationFilename); 
correctImageOrientation($destinationFilename); 

function correctImageOrientation($filename) { 
    if (function_exists('exif_read_data')) { 
    $exif = exif_read_data($filename); 
    if($exif && isset($exif['Orientation'])) { 
     $orientation = $exif['Orientation']; 
     if($orientation != 1){ 
     $img = imagecreatefromjpeg($filename); 
     $deg = 0; 
     switch ($orientation) { 
      case 3: 
      $deg = 180; 
      break; 
      case 6: 
      $deg = 270; 
      break; 
      case 8: 
      $deg = 90; 
      break; 
     } 
     if ($deg) { 
      $img = imagerotate($img, $deg, 0);   
     } 
     // then rewrite the rotated image back to the disk as $filename 
     imagejpeg($img, $filename, 95); 
     } // if there is some rotation necessary 
    } // if have the exif orientation info 
    } // if function exists  
} 
+0

parece que no funciona. 'correctImageOrientation ($ destinationFilename);' no funciona con $ destinationFilename como la ruta absoluta. Alguna idea ? – Jeremy

+0

Éste trabajó para mí. Gracias Wes! – balslev

+0

@Wes gracias amigo .es trabajo para mí :) – Gulshan

Cuestiones relacionadas