可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I've built a website which allows image uploading and once an image is uploaded , some specific information about the photo is displayed.
Uploading pictures from computers works just fine , the problem comes up when I'm trying to upload an image from a smartphone. The upload success but it seems like a major part of the data that is displayed when uploading from computer is now missing.
This code section is the one that actually retrieves and display the data :
$location = $_FILES["pic"]["tmp_name"];
$data = exif_read_data($location);
var_dump($data);
the var_dump($data)
actually dumps different data in computers and smartphones.
EDIT : Apparently it works just fine with Andoroid smartphones, the problem only comes up when I try to upload images from iPhone
For example, var_dump
from computer upload :
array(49) {
["FileName"]=> string(10) "php2D4.tmp"
["FileDateTime"]=> int(1367318152)
["FileSize"]=> int(30357)
["FileType"]=> int(2)
["MimeType"]=> string(10) "image/jpeg"
["SectionsFound"]=> string(24) "ANY_TAG, IFD0, EXIF, GPS"
["COMPUTED"]=> array(6) {
["html"]=> string(24) "width="320" height="240""
["Height"]=> int(240)
["Width"]=> int(320)
["IsColor"]=> int(1)
["ByteOrderMotorola"]=> int(1)
["ApertureFNumber"]=> string(5) "f/2.8"
}
["Make"]=> string(5) "Apple"
["Model"]=> string(8) "iPhone 4"
["Orientation"]=> int(3)
["XResolution"]=> string(4) "72/1"
["YResolution"]=> string(4) "72/1"
["ResolutionUnit"]=> int(2)
["Software"]=> string(5) "6.1.3"
["DateTime"]=> string(19) "2013:04:26 23:57:43"
["YCbCrPositioning"]=> int(1)
["Exif_IFD_Pointer"]=> int(204)
["GPS_IFD_Pointer"]=> int(594)
["ExposureTime"]=> string(4) "1/15"
["FNumber"]=> string(4) "14/5"
["ExposureProgram"]=> int(2)
["ISOSpeedRatings"]=> int(1000)
["ExifVersion"]=> string(4) "0221"
["DateTimeOriginal"]=> string(19) "2013:04:26 23:57:43"
["DateTimeDigitized"]=> string(19) "2013:04:26 23:57:43"
["ComponentsConfiguration"]=> string(4) ""
["ShutterSpeedValue"]=> string(9) "4889/1250"
["ApertureValue"]=> string(9) "4281/1441"
["BrightnessValue"]=> string(10) "-3581/1451"
["MeteringMode"]=> int(5)
["Flash"]=> int(24)
["FocalLength"]=> string(5) "77/20"
["SubjectLocation"]=> array(4) {
[0]=> int(1295)
[1]=> int(967)
[2]=> int(699)
[3]=> int(696)
}
["FlashPixVersion"]=> string(4) "0100"
["ColorSpace"]=> int(1)
["ExifImageWidth"]=> int(2592)
["ExifImageLength"]=> int(1936)
["SensingMethod"]=> int(2)
["ExposureMode"]=> int(0)
["WhiteBalance"]=> int(0)
["FocalLengthIn35mmFilm"]=> int(35)
["SceneCaptureType"]=> int(0)
["GPSLatitudeRef"]=> string(1) "N"
["GPSLatitude"]=> array(3) {
[0]=> string(4) "31/1"
[1]=> string(8) "5854/100"
[2]=> string(3) "0/1"
}
["GPSLongitudeRef"]=> string(1) "E"
["GPSLongitude"]=> array(3) {
[0]=> string(4) "34/1"
[1]=> string(8) "4684/100"
[2]=> string(3) "0/1"
}
["GPSTimeStamp"]=> array(3) {
[0]=> string(4) "20/1"
[1]=> string(4) "57/1"
[2]=> string(8) "4272/100"
}
["GPSImgDirectionRef"]=> string(1) "T"
["GPSImgDirection"]=> string(9) "48089/465"
}
var_dump
from smartphone upload:
array(12) {
["FileName"]=> string(9) "phpSzwfPw"
["FileDateTime"]=> int(1367318054)
["FileSize"]=> int(1778041)
["FileType"]=> int(2)
["MimeType"]=> string(10) "image/jpeg"
["SectionsFound"]=> string(19) "ANY_TAG, IFD0, EXIF"
["COMPUTED"]=> array(5) {
["html"]=> string(26) "width="2592" height="1936""
["Height"]=> int(1936)
["Width"]=> int(2592)
["IsColor"]=> int(1)
["ByteOrderMotorola"]=> int(1)
}
["Orientation"]=> int(3)
["Exif_IFD_Pointer"]=> int(38)
["ColorSpace"]=> int(1)
["ExifImageWidth"]=> int(2592)
["ExifImageLength"]=> int(1936)
}
Here's the computer var_dump($_FILES)
:
array(1)
{ ["pic"]=> array(5)
{ ["name"]=> string(18) leaf2.JPG"
["type"]=> string(10) "image/jpeg"
["tmp_name"]=> string(14) "/tmp/phpzeDUs9"
["error"]=> int(0)
["size"]=> int(46439) } }
Here's the iPhone results var_dump($_FILES)
:
array(1) { ["pic"]=> array(5)
{ ["name"]=> string(9) "image.jpg"
["type"]=> string(10) "image/jpeg"
["tmp_name"]=> string(14) "/tmp/phplPUZky"
["error"]=> int(0) ["size"]=> int(1455577) } }
EDIT : Here is the uploading form HTML code:
<form action="results.php" id="upload-image" method="post" enctype="multipart/form-data">
<div class="fileupload fileupload-new" data-provides="fileupload">
<div class="fileupload-preview thumbnail" style="width: 200px; height: 150px;"></div>
<div>
<span class="btn btn-file"><span class="fileupload-new">Select image</span><span class="fileupload-exists">Change</span><input type="file" name="pic" id="pic" accept="image/*"/></span>
<a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
<button type="submit" class="btn">Upload</button>
</br>
<span class="upload-error"></span>
</div>
</form>
What might cause it?
回答1:
The problem
It is correct that the iphone(ipad, etc, i'll just call it iphone from now on) strips exif data. This is also not a bug on the iphone but actually a feature.
One of the main reasons android users don't like the iphone and iphone users don't like the androids, is because the iphone is very limited (in terms of freedom to change, alter, etc). You can not just run downloaded apps, have limited access to settings, etc.
This is because the apple strategy is to create a fail-safe product. "If you can not do strange things, strange things will not happen".It tries to protect the user in every way imaginable. It also protects the user when uploading images. In the exif there may be data that can hurt the users privacy. Things like GPS coordinates, but even a timestamp can hurt a user (imagine you uploading a beach picture with a timestamp from a moment you reported in sick with the boss).
So basically it is a safety meassure to strip all exif data. Myself and a lot of other people do not agree with this strategy, but there is nothing we can do about it unfortunately.
The solution
Update: This does not work. (thanks likeitlikeit for this info)
Luckily you can get around this problem. Javascript comes to the rescue. With javascript you can read the exif data and send it with you photo by adding some extra POST data.
please note: this solution was presented to me by another developer and is not yet tested.
Sources
You are asking for credible sources. Unfortunately they are hard to find as apple is not talking as always and therefore all information i have is hearsay.
perhaps one of the more reliable sources i can present is one of the flickr staffmembers who confirms that the root cause is mobile safari stripping the exif.
http://www.flickr.com/help/forum/en-us/72157632100391901/#reply72157632135956813
回答2:
if the pic is emailed from iphone and saved to a mac, the exif data is preserved. If its copied via IMage Capture to the mac, exif data is preserved. Only if uploaded to a service from the camera role is exif data not sent with the upload.
回答3:
There are no official statements from Apple about this feature, although there is a number of people asking about this even on the Apple forums. Actually, from what's reported around the 'net, this not only happens to uploads in Safari from the iPhone, but also for emailed attachments.
However, it's clear that there are a lot of people affected by this. Flickr seems to be a major victim, but there's others too.
Luckily, nowadays there are ways of accessing raw file data for <input type="file">
tags. This allows you to take the EXIF information you want, put it into a hidden form field, and send it along with the actual file upload. I adapted a jsfiddle from this answer to showcase what I mean by that:
Have a look.
UPDATE: JavaScript is of no help
This seems not to have the desired effect on current-generation iOS devices, as the FileReader
API also only gets access to a sanitized version of the file.
回答4:
Unfortunately, itamar (op) if you upload from iphone to a server (as is my case), the IFDO: MAKE is stripped. If pic is saved on iphone and emailed, the data is there.
I need the MAKE info in order to rotate photos correctly. ORIENTATION value is different for Apple and Android and if I had the MAKE i could code to adapt. Cannot understand what the secrecy concerns could be with knowing what device took the picture.
Short of Apple allowing user to select PIC data info to be uploaded, maybe in SETTINGS,
possible solutions:
- creating code to UPLOAD saved file (not share the picture) to server location and then attaching/adding to final place
- using commercial apps to upload, like http://www.transloadit.com
- rather than depending upon the EXIF data of MAKE, I just decided on finding out the device and o/s used to send data. Will explore "client_agent" as starting point.
Just got this idea from looking at the RESULT JSON from uploading to TRANSLOADIT. It clearly has the data we need:
"client_agent": "Mozilla/5.0 (iPad; CPU OS 7_1_1 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) CriOS/34.0.1847.18 Mobile/11D201 Safari/9537.53",
If they can "see" the o/s and device, so can we.
If we get that data, then it can be added to pic EXIF and used elsewhere.
Hope this helped.
EDIT: data from Windows PC to illustrate when using "echo $_SERVER['HTTP_USER_AGENT'] . "\n\n";"
FROM PC: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 File
FROM IPAD: "Mozilla/5.0 (iPad; CPU OS 7_1_1 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) CriOS/34.0.1847.18 Mobile/11D201 Safari/9537.53",
EDIT: added rference to php.net and get browser:
http://www.php.net/manual/en/function.get-browser.php
回答5:
I just tried another browser, Opera Mini, and it worked! Got all my exif data!
回答6:
I am currently using iOS 8.1.1 and I also noticed this unlovely behavior of cutting certain Exif data from photos when uploading via mobile safari. I noticed the same behavior with a fresh installation of:
- Opera mini
- Chrome
- Mercury
So my assumption is that behavior is not browser related, but its the camera app when transferring the photo to another application (not authorized by Apple).
Does anyone found an official statement from Apple for this Exif data cutting?
回答7:
I also have a similar issue copying from an iPhone (doesn't seem to matter what iOS/iPhone combo as it's been happening for years) to a Windows 7 machine (also tried on various machines). If I copy a jpg file from the phone to the PC a large minority of pictures have their EXIF information severely deleted. Which is very annoying when time stamps and GPS info goes astray. What's even more strange is that I can recover the 'Date Taken' if I view the jpg in MS's Picture Gallery and look at the image's date taken stamp which is still present - Change the date up one and enter then back down one and the date taken stamp the will reappear in the file within Windows Explorer.
This is more weird behaviour on top of weird behaviour and very annoying to boot.
You must not do any rotation on the images or any other editing otherwise until after the PG fix or you won't be able to reclaim the date taken stamp.
For further info: I do not have iTunes installed as this causes other non-related issues.
So to recap - iPhone connected to a PC, copying jpg files over via Windows Explorer and some of the files will apparently lose their EXIF info.
回答8:
Been testing on iphone 6 for mobile image upload. To cater for the orientation for iPhone. You must be ready for the two type of image upload. The front camera and the back camera. To get the orientation from the front *selfie camera you must do the following.
First store the image to your destination folder on the server.
$image = imagecreatefromjpeg($source_url);
imagejpeg($image, $destination_url, $quality);
From there onward you read the EXIF from the created destination file
$exif = exif_read_data($destination_url, 0, true);
if(!empty($exif['IFD0']['Orientation'])) {
//rotate accordingly
}
This will give you orientation number to rotate it accordingly.
As for the back camera you are able to read directly from the source URL. The file posted from the upload form. without having to store 1st then read the EXIF
$exif = exif_read_data($source_url);
if(!empty($exif['Orientation'])) {
//rotate accordingly
}
回答9:
I think this has been resolved now with the newer version (I don't exactly which one) of iOS. I can't be 100% sure about this.
I've just noticed recently that this has started working on a few different iPhones I've tested that have iOS 9.2 installed.
So if all of you could whip out you iPhones and start testing it would be great to see if this has been resolved.