В настоящее время работает с PHP и iMagick для разработки веб-приложения для печати плакатов.
Это пример изображения, который я использую для тестирования функций загрузки / редактирования изображений приложения:
Изображение содержит следующие данные EXIF:
[FileName] => 1290599108_IMG_6783.JPG [FileDateTime] => 1290599109 [FileSize] => 4275563 [FileType] => 2 [MimeType] => image/jpeg [SectionsFound] => ANY_TAG, IFD0, THUMBNAIL, EXIF, INTEROP, MAKERNOTE [COMPUTED] => Array ( [html] => width="3504" height="2336" [Height] => 2336 [Width] => 3504 [IsColor] => 1 [ByteOrderMotorola] => 0 [CCDWidth] => 22mm [ApertureFNumber] => f/5.6 [UserComment] => [UserCommentEncoding] => UNDEFINED [Thumbnail.FileType] => 2 [Thumbnail.MimeType] => image/jpeg ) [Make] => Canon [Model] => Canon EOS 30D [Orientation] => 6 [XResolution] => 72/1 [YResolution] => 72/1 [ResolutionUnit] => 2 [DateTime] => 2009:08:31 08:23:49 [YCbCrPositioning] => 2 [Exif_IFD_Pointer] => 196
Однако – iMagick, когда __construct'ed с этим изображением, автоматически поворачивает его на 90 градусов CCW в соответствии с [Orientation] => 6
(я думаю!). В результате …
Я бы хотел узнать …
Как сохранить исходную ориентацию изображения, просматриваемого в верхней части страницы? И возможно ли это, если отключить автоматическое вращение, выполняемое iMagick?
Большое спасибо
UPDATE: вот решение, которое я придумал … Он будет фиксировать ориентацию, основанную на ориентации в данных EXIF
public function fixOrientation() { $exif = exif_read_data($this->imgSrc); $orientation = $exif['Orientation']; switch($orientation) { case 6: // rotate 90 degrees CW $this->image->rotateimage("#FFF", 90); break; case 8: // rotate 90 degrees CCW $this->image->rotateimage("#FFF", -90); break; } }
Попробуйте Imagick::setImageOrientation
. Поэкспериментируйте с доступными константами .
«Тем не менее – iMagick, когда __construct'ed с этим изображением, автоматически поворачивает его на 90 градусов CCW в соответствии с [Ориентация] => 6 (я думаю!)».
Проблема на самом деле противоположна этому. Imagick не поворачивает изображение автоматически. Вы видите это правильно в другом программном обеспечении / вашем веб-браузере, потому что эти программы автоматически вращают его на основе информации EXIF. Некоторые операции в Imagick заставят вас потерять правильную информацию EXIF (копирование изображения, thumbnailImage (), stripImage () и других манипуляций). Итак, что вам нужно сделать в этом случае, на самом деле физически вращать изображение.
Ответ от ajmicek хорош, но его можно немного улучшить, используя собственные встроенные функции Imagick, а не функции PHP EXIF. Также этот фрагмент, кажется, был частью класса, поэтому он не может использоваться как отдельная функция as-is. Также рекомендуется установить правильную ориентацию EXIF с помощью setImageOrientation () после ее поворота.
// Note: $image is an Imagick object, not a filename! See example use below. function autoRotateImage($image) { $orientation = $image->getImageOrientation(); switch($orientation) { case imagick::ORIENTATION_BOTTOMRIGHT: $image->rotateimage("#000", 180); // rotate 180 degrees break; case imagick::ORIENTATION_RIGHTTOP: $image->rotateimage("#000", 90); // rotate 90 degrees CW break; case imagick::ORIENTATION_LEFTBOTTOM: $image->rotateimage("#000", -90); // rotate 90 degrees CCW break; } // Now that it's auto-rotated, make sure the EXIF data is correct in case the EXIF gets saved with the image! $image->setImageOrientation(imagick::ORIENTATION_TOPLEFT); }
Пример использования:
$image = new Imagick('my-image-file.jpg'); autoRotateImage($image); // - Do other stuff to the image here - $image->writeImage('result-image.jpg');
Хорошее начало – несколько дополнений, чтобы сделать функцию более надежной. Во-первых, случай 3 возникает, когда изображение отображается вверх дном. Существует большая иллюстрация различных кодов ориентации Calvin Hass . Возможно, что информация о ориентации может отображаться в другой части массива exif_read_data
(в зависимости от модели камеры, я думаю), поэтому я попытался учесть это в моем примере кода.
Что-то вроде этого:
public function fixOrientation() { $exif = exif_read_data($this->imgSrc); if( isset($exif['Orientation']) ) $orientation = $exif['Orientation']; elseif( isset($exif['IFD0']['Orientation']) ) $orientation = $exif['IFD0']['Orientation']; else return false; switch($orientation) { case 3: // rotate 180 degrees $this->image->rotateimage("#FFF", 180); break; case 6: // rotate 90 degrees CW $this->image->rotateimage("#FFF", 90); break; case 8: // rotate 90 degrees CCW $this->image->rotateimage("#FFF", -90); break; } }
Преобразование & save оставляет вас без предыдущей информации EXIF, включая Orientation
. Отсутствие Orientation
в преобразованном изображении предотвратит дальнейшую обработку от попыток «исправить» вещи путем вращения снова. Я действительно хочу, чтобы Imagick поддерживал ImageMagick's -auto-orient
, но хорошо.
О, также: вращение – операция с потерями (если вы не используете jpegtran), поэтому вы должны стараться делать это только в сочетании с изменением размера или другим преобразованием.
Этот код в отличном ответе orrd требует iMagick версии 6.3+ .:
$ Image-> setImageOrientation (Imagick :: ORIENTATION_TOPLEFT);
Работает отлично и заботится о различиях ориентации устройств / устройств. Не будет работать с 6.2.
Я закодировал, чтобы получить устройство. Здесь, в случае, если кому-то это нужно.
$ua = $_SERVER['HTTP_USER_AGENT']; $strcut = stristr($ua, '(')."<br>"; $textlen = strpos($strcut,";"); $deviceos = substr($strcut,1,($textlen-1)); echo "Device O/S: * $deviceos"."<br>";