PHP read_exif_data 和调整方向
如果方向关闭,我将使用以下代码来旋转上传的 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';
}
我从 jpeg 读取 EXIF 数据的方式是否有问题?它没有按预期旋转图像。
这就是我运行 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) }
I am using the following code to rotate an uploaded jpeg image if the orientation is off. I am only having problems with images uploaded from iPhones and 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';
}
Am I doing something wrong with the way I am reading the EXIF data from the jpeg? It is not rotating the images as it is supposed to.
This is what happens when I run a 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) }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
根据丹尼尔的代码,我编写了一个函数,该函数可以在必要时简单地旋转图像,而无需重新采样。
GD
一行版 (GD)
ImageMagick
Based on Daniel's code I wrote a function that simply rotates an image if necessary, without resampling.
GD
One line version (GD)
ImageMagick
imagerotate 的文档引用了与第一个参数不同的类型你使用:
这是使用此功能的一个小示例:
The documentation for imagerotate refers to a different type for the first parameter than you use:
Here is a small example for using this function:
对于上传图像的人来说,功能更简单,它只是在必要时自动旋转。
Simpler function for those uploading an image, it just autorotates if necessary.
为什么没有人考虑镜像案例 2、4、5、7?
exif定向地还有4个案例:
这是采用文件名的完整解决方案:
Why is nobody considering mirrored cases 2,4,5,7?
There are 4 more cases in exif orientation land:
Here is a complete solution taking a filename:
以防万一有人遇到这个。据我所知,上面的一些 switch 语句是错误的。
根据此处的信息,应该是:
Just in case someone comes across this. From what I can make out some of the switch statements above are wrong.
Based on information here, it should be:
可能值得一提的是,如果您从命令行使用 ImageMagick,则可以使用 -auto-orient 选项将根据现有 EXIF 方向数据自动旋转图像。
请注意:如果在处理之前删除了 EXIF 数据,则它将无法按所述工作。
It's probably worthwhile to mention that if you are using ImageMagick from command line, you can use the -auto-orient option which will auto rotate the image based on the existing EXIF orientation data.
Please note: If the EXIF data was stripped before the process, it will not work as described.
我讨厌附和另一组方向值,但根据我使用上面列出的任何值的经验,当直接从 iPhone 上传纵向照片时,我总是会得到颠倒的图像。这是我最终得到的 switch 语句。
I hate to chime in with yet another set of orientation values, but in my experience using any of the values listed above, I always ended up with upside down images when uploading portrait orientation shots directly from an iPhone. Here's the switch statement I ended up with.
在这里我解释了整个事情,我使用 Laravel 并使用图像干预包。
首先,我获取图像并将其发送到另一个函数以调整大小和其他一些功能,如果我们不需要这个,您可以跳过...
使用控制器中的方法获取文件,
现在,我发送它调整大小并获取图像名称和扩展名...
现在我调用我的图像方向函数,
仅此而已...
Here I'am explaining the whole thing, I use Laravel and use the Image Intervention Package.
First of all, I get my image and send it to my another function for resizing and some other functionality, if we do not need this, you can skip...
Grab the file with a method in my controller,
Now, I send it to resize and getting the image name and extension...
Now I call my image orientation function,
And That's all...
这是我的 PHP 7 函数,灵感来自@user462990:
用法:
Here is my PHP 7 function inspired by @user462990:
usage:
jhead -autorot jpegfile.jpg
也是解决此问题的有用方法。
jhead 是 Linux 中的标准程序(使用“sudo apt-get install jhead”进行安装),此选项会查看方向并仅在需要时正确且无损地旋转图像。然后它还会正确更新 EXIF 数据。
通过这种方式,您可以通过简单的一次性方式处理一个 jpeg(或一个文件夹中的多个 jpeg),从而永久解决旋转问题。
例如:
jhead -autorot *.jpg
将按照OP在最初的问题中要求的方式修复整个jpeg图像文件夹。
虽然从技术上讲它不是 PHP,但我确实阅读了此线程,然后使用我的 jhead 建议,从 PHP system() 调用调用来实现我所追求的结果,该结果与 OP 一致:旋转图像,以便任何软件(例如“fbi”) ' 在 Raspbian 中)可以正确显示它们。
有鉴于此,我认为其他人可能会从了解 jhead 如何轻松解决此问题中受益,并在此发布信息仅供参考 - 因为之前没有人提到过它。
jhead -autorot jpegfile.jpg
Is also a useful way to approach this.
jhead is a standard program in Linux (use 'sudo apt-get install jhead' to install), this option looks at the orientation and rotates the image correctly and losslessly only if it requires. It then also updates the EXIF data correctly.
In this way you can process a jpeg (or multiple jpegs in a folder) in a simple one-pass way that fixes rotation issues permanently.
E.g:
jhead -autorot *.jpg
will fix a whole folder of jpeg images in just the manner the OP requires in the initial question.
While it's not technically PHP I did read this thread and then used my jhead suggestion instead, called from a PHP system() call to achieve the results I was after which were coincident with the OPs: to rotate images so any software (like 'fbi' in Raspbian) could display them correctly.
In light of this I thought others may benefit from knowing how easily jhead solves this problem and posted the information here only for informative purposes - because no one had mentioned it previously.
我还使用了
orientate()
形式的干预,并且它的工作完美。I've also used
orientate()
form Intervention, and it works flawlessly.我认为最好的答案应该更新以考虑所有可能的 exif 方向值(从 1 到 8):
更多信息 此处。
请注意,应针对以下 exif 值翻转图像:2、4、6 和 8。
I think the best answer should be updated to take into account all possible exif orientation values (from 1 to 8):
More information here.
Note that the image should be flipped for the following exif values: 2, 4, 6, and 8.
干预图像有一个方法
orientate()
:Intervention Image has a method
orientate()
: