上传前根据 EXIF 方向定位图像 PHP
Orient image according to EXIF orientation before upload with PHP
我知道这个话题对你们大多数人来说可能很容易,但过去两天我一直在为这个问题争论不休,但没有任何进展。
我正在为自己开发一个 Web 应用程序,不需要安全性,因为它不是用于生产的。
以下脚本工作正常,当我使用以下方法直接从相机上传图片时问题仍然存在:
<input
id="photoBox"
type="file"
class="form-control-file"
accept="image/*"
capture="camera"
name="photo"/>
当我从浏览器上传时,一切正常,但是从智能手机上传时,服务器不遵守 EXIF 方向,因此图像旋转错误。
根据上传,我使用以下脚本:(也提供了 pastebin)。
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;
}
我的意图很明确。根据EXIF方向旋转img BEFORE upload,然后继续将其存储在磁盘上。
如果可能的话,我打算用完全相同的 photoPlant(arg)
函数来做。
谢谢。
嗯。在一些无法解释的反对票和来自 DinoCoderSaurus 的非常有用的评论之后,这就是我一直在寻找的答案。
我必须为 PHP7 安装并启用 Imagick。
这不是一项简单的工作,但有一些指南可供 google 使用。根据您的版本/os,安装说明会不同,因此请谨慎操作。
我的上传功能(从原来的post)在上传部分发生了变化。
上面写着:
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";
}
这解决了我所有的问题,响应时间还算合理。
希望一些像我这样的新手能从这个post.
中获得一些技能收益
作为告别笔记,我需要添加...如果您对 post 投反对票,请评论您这样做的原因,因为这个话题已经在这里讨论过无数次,但是经过 2 天的研究在这么旧的 posts 上,我没能找到 为什么 它不起作用!
特别感谢 DinoCoderSaurus,他用大约 10 个单词给我指明了正确的方向。
我知道这个话题对你们大多数人来说可能很容易,但过去两天我一直在为这个问题争论不休,但没有任何进展。
我正在为自己开发一个 Web 应用程序,不需要安全性,因为它不是用于生产的。
以下脚本工作正常,当我使用以下方法直接从相机上传图片时问题仍然存在:
<input
id="photoBox"
type="file"
class="form-control-file"
accept="image/*"
capture="camera"
name="photo"/>
当我从浏览器上传时,一切正常,但是从智能手机上传时,服务器不遵守 EXIF 方向,因此图像旋转错误。
根据上传,我使用以下脚本:(也提供了 pastebin)。
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;
}
我的意图很明确。根据EXIF方向旋转img BEFORE upload,然后继续将其存储在磁盘上。
如果可能的话,我打算用完全相同的 photoPlant(arg)
函数来做。
谢谢。
嗯。在一些无法解释的反对票和来自 DinoCoderSaurus 的非常有用的评论之后,这就是我一直在寻找的答案。
我必须为 PHP7 安装并启用 Imagick。 这不是一项简单的工作,但有一些指南可供 google 使用。根据您的版本/os,安装说明会不同,因此请谨慎操作。
我的上传功能(从原来的post)在上传部分发生了变化。 上面写着:
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";
}
这解决了我所有的问题,响应时间还算合理。 希望一些像我这样的新手能从这个post.
中获得一些技能收益作为告别笔记,我需要添加...如果您对 post 投反对票,请评论您这样做的原因,因为这个话题已经在这里讨论过无数次,但是经过 2 天的研究在这么旧的 posts 上,我没能找到 为什么 它不起作用!
特别感谢 DinoCoderSaurus,他用大约 10 个单词给我指明了正确的方向。