Сориентируйте изображение в соответствии с ориентацией EXIF ​​перед загрузкой с помощью PHP - PullRequest
0 голосов
/ 07 января 2019

Я знаю, что эта тема, вероятно, проста для большинства из вас, но я боролся за это последние 2 дня без какого-либо прогресса.

Я делаю веб-приложение для себя, безопасность не требуется, поскольку он не предназначен для производства.

Следующие сценарии работают нормально, проблема остается, когда я загружаю изображение непосредственно с камеры, используя:

<input
id="photoBox"
type="file"
class="form-control-file"
accept="image/*"
capture="camera"
name="photo"/>

Когда я загружаю из браузера все работает нормально, однако со смартфона сервер не учитывает ориентацию EXIF, поэтому изображения вращаются неправильно.

Для загрузки я использую следующий скрипт: (также предоставляется pastebin).

https://pastebin.com/mvgah9Ud

function photoPlant($pID){
// db
include "includes/dbConfig.php";
// init
$out = null;
// gen hash
$varA = microtime();
$varB = time();
$varC = $varA . $varB;
$hash = md5($varC);
// prepare upload
$currentDir = getcwd();
$uploadDirectory = "/gallery/";
$errors = []; // Store all foreseen and unforseen errors here
$fileExtensions = ['jpeg','jpg','png', '']; // Get all the file 
extensions, including empty for mobile
// reformat empty file extension
if ($fileExtension === ""){
  $fileExtension = "jpg";
}
$fileName = $_FILES['photo']['name'];
$fileTmpName = $_FILES['photo']['tmp_name'];
$fileSize = $_FILES['photo']['size'];
$fileType = $_FILES['photo']['type'];
$fileExtension = strtolower(end(explode('.',$fileName)));
// reformat filename
$fileName = $hash . "." . $fileExtension;
$uploadPath = $currentDir . $uploadDirectory . basename($fileName);
if (! in_array($fileExtension,$fileExtensions)) {
    $errors[] = "This file extension is not allowed. Please upload a 
JPEG or PNG file";
}
if ($fileSize > 8000000) {
    $errors[] = "This file is more than 8MB. Sorry, it has to be less 
than or equal to 8MB";
}
if (empty($errors)) {
    $didUpload = move_uploaded_file($fileTmpName, $uploadPath);
    if ($didUpload) {
        $out .= "ok"; // everything is ok give feedback ok
    } else {
        $out .= "An error occurred somewhere. Try again or contact the 
admin";
    }
} else {
    foreach ($errors as $error) {
        $out .= $error . "These are the errors" . "\n";
    }
}
  // store img on db
  // prepare data
  $timeStamp = time();
  // query
  $query = mysqli_query($con, "INSERT INTO photo_table 
(photo_parent_id, photo_name, photo_timestamp) VALUES ($pID, 
'$fileName', $timeStamp)");
  // run query
  if (!$query){
    $out = mysqli_error($con);
  }
// return
return $out;
}

Мои намерения ясны. Поверните img ПЕРЕД загрузкой в ​​соответствии с ориентацией EXIF ​​и затем сохраните ее на диске. Если возможно, я собираюсь сделать это в той же самой функции photoPlant(arg).

Спасибо.

1 Ответ

0 голосов
/ 08 января 2019

Хорошо. После нескольких необъяснимых отрицательных голосов и очень полезного комментария от DinoCoderSaurus это ответ, который я искал.

Мне пришлось установить и включить Imagick для PHP7 . Это была не простая работа, но есть несколько руководств, доступных для Google. В зависимости от вашей версии / os примечания по установке отличаются , поэтому действуйте осторожно.

Моя функция загрузки (из исходного сообщения) изменена в части загрузки. Где написано:

if (empty($errors)){
// old code here.
}

Это было изменено для следующей проверки:

if (empty($errors)) {
    // this is my new validation code.
    $img = new Imagick($fileTmpName);
    $orient = $img->getImageOrientation();
    if($orient === 6){
        // we need to rotate it 90deg
        $img->rotateImage("rgba(255, 255, 255, 0.0)", 90);
    }
    if ($orient === 3){
        // we need to rotate it 180deg
        $img->rotateImage("rgba(255, 255, 255, 0.0)", 180);
    }
    // Note that imagick does the storage for me as well!
    $img->writeImage("gallery/" . $fileName);
}
else{
    $out .= "Errors on upload";
}

Это исправило ВСЕ мои проблемы с достаточно хорошим временем ответа. Надеюсь, что некоторые новички, как я, получат некоторую прибыль от этого поста.

В качестве прощальной записки мне нужно добавить ... Если вы понижаете рейтинг поста, прокомментируйте причину, по которой вы это сделали, потому что эта тема уже обсуждалась здесь бесчисленное количество раз, но после 2-х дней изучения ТАКИХ старых постов я не сделал ПОЧЕМУ это не сработало!

Особая благодарность DinoCoderSaurus, который направил меня в правильном направлении примерно с 10 словами.

...