Wykryj orientację EXIF ​​i obróć obraz za pomocą ImageMagick

83

Wydaje się, że lustrzanki cyfrowe Canon zapisują zdjęcia w orientacji poziomej i używają exif::orientationich do obracania.

Pytanie: W jaki sposób można użyć imagemagick do ponownego zapisania obrazu w zamierzonej orientacji przy użyciu danych orientacji exif, tak aby dane exif nie były już wyświetlane we właściwej orientacji?

Nyxynyx
źródło
php.net/manual/en/function.exif-read-data.php Wyodrębnij parametr obrotu, przetestuj go, obróć obraz, jeśli to konieczne.
Marc B

Odpowiedzi:

132

Aby to zrobić, użyj opcji auto-orientacji programu ImageMagick convert.

convert your-image.jpg -auto-orient output.jpg

Lub użyj, mogrifyaby zrobić to na miejscu

mogrify -auto-orient your-image.jpg
dlemstra
źródło
12
Nie zapomnij, że możesz użyć mogrifyzamiast, convertjeśli chcesz zastąpić istniejący plik (w miejscu), co jest przydatne, gdy chcesz zapełnić katalog.
zanedp
1
Wydaje się, że nie działa we wszystkich przypadkach. Mam przynajmniej przypadek, że GIMP pyta mnie, czy chcę naprawić obrót, ale konwersja po prostu pozostawia obraz tak, jak jest (pozostawiając prawdziwą górną część obrazu w prawej części).
xarlymg89
49

Sposób PHP Imagick polega na przetestowaniu orientacji obrazu i odpowiednim obróceniu / odwróceniu obrazu:

function autorotate(Imagick $image)
{
    switch ($image->getImageOrientation()) {
    case Imagick::ORIENTATION_TOPLEFT:
        break;
    case Imagick::ORIENTATION_TOPRIGHT:
        $image->flopImage();
        break;
    case Imagick::ORIENTATION_BOTTOMRIGHT:
        $image->rotateImage("#000", 180);
        break;
    case Imagick::ORIENTATION_BOTTOMLEFT:
        $image->flopImage();
        $image->rotateImage("#000", 180);
        break;
    case Imagick::ORIENTATION_LEFTTOP:
        $image->flopImage();
        $image->rotateImage("#000", -90);
        break;
    case Imagick::ORIENTATION_RIGHTTOP:
        $image->rotateImage("#000", 90);
        break;
    case Imagick::ORIENTATION_RIGHTBOTTOM:
        $image->flopImage();
        $image->rotateImage("#000", 90);
        break;
    case Imagick::ORIENTATION_LEFTBOTTOM:
        $image->rotateImage("#000", -90);
        break;
    default: // Invalid orientation
        break;
    }
    $image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
}

Funkcji można użyć w następujący sposób:

$img = new Imagick('/path/to/file');
autorotate($img);
$img->stripImage(); // if you want to get rid of all EXIF data
$img->writeImage();
tarleb
źródło
2
To rozwiązanie działa! Wypróbowałem tylko 1 obraz i jest oczywiście 8, ale dam ci znać, jak poszło. Dla mnie to było rotateImage, -> rotate just breaks
Jack Franzen
3
Dzięki, naprawiłem rotateImagerzeczy. Jeśli chcesz przetestować wszystkie orientacje: istnieje zgrabne repozytorium github, które ma obraz dla każdej wartości exif.
tarleb
dzięki! pracował w c #. potrzebowałem tylko małej konwersji.
Alvin