2010-09-07 8 views
19

Jeśli robię zdjęcie aparatem, przechowuje on orientację/kąt aparatu, więc gdy oglądam obraz na komputerze z dobrą aplikacją, pokazuje on automatyczne obracanie na 0.Jak wykryć kąt strzału zdjęcia i automatycznie obrócić widok strony internetowej, tak jak robią to aplikacje komputerowe?

Ale kiedy wgrywam do strona internetowa pokazuje oryginalny kąt, więc obraz nie wygląda dobrze.

W jaki sposób można to wykryć za pomocą PHP i obrócić obraz, i wyczyścić tę flagę kąta z jej meta informacji.

Odpowiedz

23

W tym celu należy odczytać informacje EXIF ​​z pliku JPEG. Możesz to zrobić z rozszerzeniem PHP exif lub z PEL.

Zasadniczo musisz przeczytać w pliku flagę Orientation. Oto przykład użycia rozszerzenia PHP exif i WideImage do manipulowania obrazem.

<?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

nie był pewien, jak użyć klasy Andrew pisał, więc po prostu umieścić funkcję w moim kontrolera i przekazywane zmienna obrazu i orientacja do niego. Praca jest jak mistrz. Jedynym komentarzem jest sprawdzenie, czy obraz jest typu JPEG przed wywołaniem exif_read_data, w przeciwnym razie php zgłosi błąd. – w00tw00t111

+0

Pamiętaj, że ten kod wymaga zainstalowania biblioteki PHP WideImage. (Andrew o tym wspomina, ale wiem, że większość ludzi po prostu skopiuje i wklei kod, a potem nie zrozumie, dlaczego nie działa dla nich.) Jeśli nie chcesz instalować WideImage, istnieją inne przykłady tego, jak rób to bez niego. – orrd

+0

@ w00tw00t111 to typ pliku innego niż JPEG, który powoduje następujący błąd? 'Błąd krytyczny: brak wyjątku" WideImage_UnknownImageOperationException "z komunikatem" Nie można załadować "operacji exifOrient." " –

2

Flaga rotacji jest zapisywana jako część danych EXIF ​​(więcej informacji można znaleźć w artykule this article).

Będziesz musiał odczytać flagę rotacji z danych EXIF ​​w PHP, a następnie obrócić obraz, aby dopasować. Istnieje wiele bibliotek PHP EXIF, jeśli masz serwer WWW skonfigurowany z zainstalowanym rozszerzeniem, będziesz mógł korzystać z PHP provided library.

Sugerowałbym obracanie obrazu raz podczas przesyłania (np. Przy użyciu GD library - większość instalacji PHP w tych dniach wydaje się być z nim), więc nie musisz martwić się czyszczenie danych rotacji EXIF ​​(nie wiesz jak łatwo jest to z PHP, nigdy tego nie próbowałem).

14

Jeśli tylko chcesz używać GD i rozszerzenie php EXIF ​​można użyć to:

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

zmodyfikowałem przykład Chrisa dodać czek dla funkcji exif, usuń mirroring, i również, aby zapisać plik z powrotem do systemu plików przy użyciu tej samej nazwy pliku. W ten sposób można wywołać tę funkcję tuż po wywołaniu move_uploaded_file, tak:

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

wydaje się nie działać. 'correctImageOrientation ($ destinationFilename);' nie działa, ponieważ $ destinationFilename jest ścieżką bezwzględną. Dowolny pomysł ? – Jeremy

+0

Ten pracował dla mnie. Dzięki Wes! – balslev

+0

@We dzięki kumplowi .its dla mnie pracują :) – Gulshan

Powiązane problemy