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?
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
I just tried another browser, Opera Mini, and it worked! Got all my exif data!
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.
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.
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.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.