Я использую следующий код для поворота загруженного jpeg-изображения, если ориентация выключена. У меня только проблемы с изображениями, загруженными с iPhone и Android.
if(move_uploaded_file($_FILES['photo']['tmp_name'], $upload_path . $newfilename)){ chmod($upload_path . $newfilename, 0755); $exif = exif_read_data($upload_path . $newfilename); $ort = $exif['IFD0']['Orientation']; switch($ort) { case 3: // 180 rotate left $image->imagerotate($upload_path . $newfilename, 180, -1); break; case 6: // 90 rotate right $image->imagerotate($upload_path . $newfilename, -90, -1); break; case 8: // 90 rotate left $image->imagerotate($upload_path . $newfilename, 90, -1); break; } imagejpeg($image, $upload_path . $newfilename, 100); $success_message = 'Photo Successfully Uploaded'; }else{ $error_count++; $error_message = 'Error: Upload Unsuccessful<br />Please Try Again'; }
Я делаю что-то неправильно с тем, как я читаю данные EXIF из jpeg? Он не вращает изображения, как предполагается.
Это то, что происходит, когда я запускаю var_dump ($ exif);
array(41) { ["FileName"]=> string(36) "126e7c0efcac2b76b3320e6187d03cfd.JPG" ["FileDateTime"]=> int(1316545667) ["FileSize"]=> int(1312472) ["FileType"]=> int(2) ["MimeType"]=> string(10) "image/jpeg" ["SectionsFound"]=> string(30) "ANY_TAG, IFD0, THUMBNAIL, EXIF" ["COMPUTED"]=> array(8) { ["html"]=> string(26) "width="2048" height="1536"" ["Height"]=> int(1536) ["Width"]=> int(2048) ["IsColor"]=> int(1) ["ByteOrderMotorola"]=> int(1) ["ApertureFNumber"]=> string(5) "f/2.8" ["Thumbnail.FileType"]=> int(2) ["Thumbnail.MimeType"]=> string(10) "image/jpeg" } ["Make"]=> string(5) "Apple" ["Model"]=> string(10) "iPhone 3GS" ["Orientation"]=> int(6) ["XResolution"]=> string(4) "72/1" ["YResolution"]=> string(4) "72/1" ["ResolutionUnit"]=> int(2) ["Software"]=> string(5) "4.3.5" ["DateTime"]=> string(19) "2011:09:16 21:18:46" ["YCbCrPositioning"]=> int(1) ["Exif_IFD_Pointer"]=> int(194) ["THUMBNAIL"]=> array(6) { ["Compression"]=> int(6) ["XResolution"]=> string(4) "72/1" ["YResolution"]=> string(4) "72/1" ["ResolutionUnit"]=> int(2) ["JPEGInterchangeFormat"]=> int(658) ["JPEGInterchangeFormatLength"]=> int(8231) } ["ExposureTime"]=> string(4) "1/15" ["FNumber"]=> string(4) "14/5" ["ExposureProgram"]=> int(2) ["ISOSpeedRatings"]=> int(200) ["ExifVersion"]=> string(4) "0221" ["DateTimeOriginal"]=> string(19) "2011:09:16 21:18:46" ["DateTimeDigitized"]=> string(19) "2011:09:16 21:18:46" ["ComponentsConfiguration"]=> string(4) "" ["ShutterSpeedValue"]=> string(8) "3711/949" ["ApertureValue"]=> string(9) "4281/1441" ["MeteringMode"]=> int(1) ["Flash"]=> int(32) ["FocalLength"]=> string(5) "77/20" ["SubjectLocation"]=> array(4) { [0]=> int(1023) [1]=> int(767) [2]=> int(614) [3]=> int(614) } ["FlashPixVersion"]=> string(4) "0100" ["ColorSpace"]=> int(1) ["ExifImageWidth"]=> int(2048) ["ExifImageLength"]=> int(1536) ["SensingMethod"]=> int(2) ["ExposureMode"]=> int(0) ["WhiteBalance"]=> int(0) ["SceneCaptureType"]=> int(0) ["Sharpness"]=> int(1) }
Документация для imagerotate относится к другому типу для первого параметра, чем вы используете:
Ресурс изображения, возвращаемый одной из функций создания изображения, например imagecreatetruecolor ().
Вот небольшой пример использования этой функции:
function resample($jpgFile, $thumbFile, $width, $orientation) { // Get new dimensions list($width_orig, $height_orig) = getimagesize($jpgFile); $height = (int) (($width / $width_orig) * $height_orig); // Resample $image_p = imagecreatetruecolor($width, $height); $image = imagecreatefromjpeg($jpgFile); imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig); // Fix Orientation switch($orientation) { case 3: $image_p = imagerotate($image_p, 180, 0); break; case 6: $image_p = imagerotate($image_p, -90, 0); break; case 8: $image_p = imagerotate($image_p, 90, 0); break; } // Output imagejpeg($image_p, $thumbFile, 90); }
Основываясь на коде Дэниела, я написал функцию, которая просто поворачивает изображение, если это необходимо, без повторной выборки.
function image_fix_orientation(&$image, $filename) { $exif = exif_read_data($filename); if (!empty($exif['Orientation'])) { switch ($exif['Orientation']) { case 3: $image = imagerotate($image, 180, 0); break; case 6: $image = imagerotate($image, -90, 0); break; case 8: $image = imagerotate($image, 90, 0); break; } } }
function image_fix_orientation(&$image, $filename) { $image = imagerotate($image, array_values([0, 0, 0, 180, 0, 0, -90, 0, 90])[@exif_read_data($filename)['Orientation'] ?: 0], 0); }
function image_fix_orientation($image) { if (method_exists($image, 'getImageProperty')) { $orientation = $image->getImageProperty('exif:Orientation'); } else { $filename = $image->getImageFilename(); if (empty($filename)) { $filename = 'data://image/jpeg;base64,' . base64_encode($image->getImageBlob()); } $exif = exif_read_data($filename); $orientation = isset($exif['Orientation']) ? $exif['Orientation'] : null; } if (!empty($orientation)) { switch ($orientation) { case 3: $image->rotateImage('#000000', 180); break; case 6: $image->rotateImage('#000000', 90); break; case 8: $image->rotateImage('#000000', -90); break; } } }
Упрощенная функция для загрузки изображения, она просто авторотирует, если необходимо.
function image_fix_orientation($filename) { $exif = exif_read_data($filename); if (!empty($exif['Orientation'])) { $image = imagecreatefromjpeg($filename); switch ($exif['Orientation']) { case 3: $image = imagerotate($image, 180, 0); break; case 6: $image = imagerotate($image, -90, 0); break; case 8: $image = imagerotate($image, 90, 0); break; } imagejpeg($image, $filename, 90); } }
Вероятно, стоит упомянуть, что если вы используете ImageMagick из командной строки, вы можете использовать опцию -auto-orient, которая автоматически поворачивает изображение на основе существующих данных ориентации EXIF.
convert -auto-orient /tmp/uploadedImage.jpg /save/to/path/image.jpg
Обратите внимание: если данные EXIF были удалены до процесса, они не будут работать, как описано.
На всякий случай кто-то сталкивается с этим. Из того, что я могу понять, некоторые из приведенных выше операторов переключения неверны.
Основываясь на информации здесь , это должно быть:
switch ($exif['Orientation']) { case 3: $image = imagerotate($image, -180, 0); break; case 6: $image = imagerotate($image, 90, 0); break; case 8: $image = imagerotate($image, -90, 0); break; }
Мне не нравится перекликаться с еще одним набором значений ориентации, но по моему опыту, используя любое из значений, перечисленных выше, я всегда получал перевернутые изображения при загрузке снимков ориентации портрет непосредственно с iPhone. Вот оператор switch, в котором я оказался.
switch ($exif['Orientation']) { case 3: $image = imagerotate($image, -180, 0); break; case 6: $image = imagerotate($image, -90, 0); break; case 8: $image = imagerotate($image, 90, 0); break; }
Здесь я объясняю все это, я использую Laravel и использую пакет Imaging Intervention.
Прежде всего, я получаю свое изображение и отправляю его на свою другую функцию для изменения размера и некоторых других функций, если нам это не нужно, вы можете пропустить …
Возьмите файл с помощью метода в моем контроллере,
public function getImageFile(Request $request){ $image = $request->image; $this->imageUpload($image); }
Теперь я отправляю его для изменения размера и получения имени и расширения изображения …
public function imageUpload($file){ ini_set('memory_limit', '-1'); $directory = 'uploads/'; $name = str_replace([" ", "."], "_", $file->getClientOriginalName()) . "_"; $file_name = $name . time() . rand(1111, 9999) . '.' . $file->getClientOriginalExtension(); //path set $img_url = $directory.$file_name; list($width, $height) = getimagesize($file); $h = ($height/$width)*600; Image::make($file)->resize(600, $h)->save(public_path($img_url)); $this->image_fix_orientation($file,$img_url); return $img_url; }
Теперь я называю свою функцию ориентации изображения,
public function image_fix_orientation($file,$img_url ) { $data = Image::make($file)->exif(); if (!empty($data['Orientation'])) { $image = imagecreatefromjpeg($file); switch ($data['Orientation']) { case 3: $image = imagerotate($image, 180, 0); break; case 6: $image = imagerotate($image, -90, 0); break; case 8: $image = imagerotate($image, 90, 0); break; } imagejpeg($image, $img_url, 90); } }
И это все…