├── .gitignore
├── composer.json
├── imageMetadataParser.php
├── license.txt
├── readme.markdown
└── test
└── test.php
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cnlpete/image-metadata-parser",
3 | "type": "library",
4 | "description": "An abstraction to Exif, ITPC and XMP",
5 | "keywords": ["php", "exif", "itpc"],
6 | "homepage": "https://github.com/cnlpete/imageMetadataParser",
7 | "license": "MIT",
8 |
9 | "require": {
10 | "php": ">=5.3.0"
11 | },
12 |
13 | "authors": [{
14 | "name": "Hauke Schade"
15 | }],
16 |
17 | "autoload": {
18 | "classmap": ["imageMetadataParser.php"]
19 | },
20 |
21 | "target-dir": ""
22 | }
23 |
--------------------------------------------------------------------------------
/imageMetadataParser.php:
--------------------------------------------------------------------------------
1 | sFilename = $sFilename;
20 | }
21 |
22 | public static function exifAvailable() {
23 | $load_ext = get_loaded_extensions();
24 | return in_array('exif', $load_ext);
25 | }
26 |
27 | public function parseExif() {
28 | $aArr = @exif_read_data($this->sFilename, 'IFD0,THUMBNAIL', true);
29 | if ($aArr === false)
30 | return false;
31 |
32 | // the date and time the image was taken
33 | if (isset($aArr['IFD0']['DateTime'])) {
34 | $iTimestamp = self::timestampFromEXIF($aArr['IFD0']['DateTime']);
35 | if ($iTimestamp !== false)
36 | $this->aAttributes['datetime'] = $iTimestamp;
37 | }
38 | else if (isset($aArr['EXIF']['DateTimeOriginal'])) {
39 | $iTimestamp = self::timestampFromEXIF($aArr['EXIF']['DateTimeOriginal']);
40 | if ($iTimestamp !== false)
41 | $this->aAttributes['datetime'] = $iTimestamp;
42 | }
43 | else if (isset($aArr['EXIF']['DateTimeDigitized'])) {
44 | $iTimestamp = self::timestampFromEXIF($aArr['EXIF']['DateTimeDigitized']);
45 | if ($iTimestamp !== false)
46 | $this->aAttributes['datetime'] = $iTimestamp;
47 | }
48 |
49 | // the images title
50 | if (isset($aArr['COMPUTED']['UserComment']))
51 | $this->aAttributes['title'] = trim($aArr['COMPUTED']['UserComment']);
52 |
53 | // the thumbnails mimetype
54 | if (isset($aArr['COMPUTED']['Thumbnail.MimeType']))
55 | $this->aAttributes['thumbnailtype'] = $aArr['COMPUTED']['Thumbnail.MimeType'];
56 |
57 | // gps
58 | if (isset($aArr['GPS']))
59 | $this->aAttributes['gps'] = $aArr['GPS'];
60 |
61 | // the exif orientation
62 | if (isset($aArr['IFD0']['Orientation']))
63 | $this->aAttributes['orientation'] = $aArr['IFD0']['Orientation'];
64 |
65 | return true;
66 | }
67 |
68 | public function parseIPTC() {
69 | $aArr = @exif_read_data($this->sFilename, 'IDF0', true);
70 | $size = getimagesize($this->sFilename, $info);
71 | if(!isset($info['APP13']))
72 | return false;
73 |
74 | $iptc = iptcparse($info['APP13']);
75 |
76 | if (isset($iptc["2#120"][0])) # caption
77 | $this->aAttributes['title'] = trim($iptc["2#120"][0]);
78 | else if (isset($iptc["2#105"][0])) # headline
79 | $this->aAttributes['title'] = trim($iptc["2#105"][0]);
80 | else if (isset($iptc["2#005"][0])) # graphic name
81 | $this->aAttributes['title'] = trim($iptc["2#005"][0]);
82 |
83 | if (isset($iptc["2#055"][0]) && isset($iptc["2#060"][0])) {# creation date
84 | $iTimestamp = self::timestampFromIPTC($iptc["2#055"][0], $iptc["2#060"][0]);
85 | if ($iTimestamp !== false)
86 | $this->aAttributes['datetime'] = $iTimestamp;
87 | }
88 |
89 | return true;
90 | }
91 |
92 | private function timestampFromIPTC( $date, $time ) {
93 | if ( ! ( preg_match('/\d\d\d\d\d\d[-+]\d\d\d\d/', $time)
94 | && preg_match('/\d\d\d\d\d\d\d\d/', $date)
95 | && substr($date, 0, 8) !== '00000000' ) ) {
96 | // wrong dates
97 | return false;
98 | }
99 |
100 | $iTimestamp = mktime(
101 | substr( $time, 0, 2 ),
102 | substr( $time, 2, 2 ),
103 | substr( $time, 4, 2 ),
104 | substr( $date, 4, 2 ),
105 | substr( $date, 6, 2 ),
106 | substr( $date, 0, 4 ));
107 |
108 | $iDiff = ( intval( substr( $time, 7, 2 ) ) *60*60 )
109 | + ( intval( substr( $time, 9, 2 ) ) * 60 );
110 | if ( substr( $time, 6, 1 ) === '-' )
111 | $iDiff = - $iDiff;
112 |
113 | return $iTimestamp + $iDiff;
114 | }
115 |
116 | private function timestampFromEXIF( $string ) {
117 | if ( ! ( preg_match('/\d\d\d\d:\d\d:\d\d \d\d:\d\d:\d\d/', $string))) {
118 | // wrong date
119 | return false;
120 | }
121 |
122 | $iTimestamp = mktime(
123 | substr( $string, 11, 2 ),
124 | substr( $string, 14, 2 ),
125 | substr( $string, 17, 2 ),
126 | substr( $string, 5, 2 ),
127 | substr( $string, 8, 2 ),
128 | substr( $string, 0, 4 ));
129 |
130 | return $iTimestamp;
131 | }
132 |
133 | public function hasTitle() {
134 | return isset($this->aAttributes['title']);
135 | }
136 | public function getTitle() {
137 | return (string)$this->aAttributes['title'];
138 | }
139 |
140 | public function hasThumbnail() {
141 | return (isset($this->aAttributes['thumbnailtype']));
142 | }
143 | public function getThumbnail() {
144 | return exif_thumbnail($this->sFilename);
145 | }
146 | public function getThumbnailContentType() {
147 | return $this->aAttributes['thumbnailtype'];
148 | }
149 |
150 | public function hasDateTime() {
151 | return isset($this->aAttributes['datetime']);
152 | }
153 | public function getDateTime() {
154 | return (int)$this->aAttributes['datetime'];
155 | }
156 |
157 | public function hasGPS() {
158 | return isset($this->aAttributes['gps']) &&
159 | isset($this->aAttributes['gps']['GPSLongitude'][0]) &&
160 | isset($this->aAttributes['gps']['GPSLatitude'][0]);
161 | }
162 | public function getGPS(&$dLat, &$dLong) {
163 | $latFirst = explode("/", $this->aAttributes['gps']['GPSLatitude'][0]);
164 | $latSecond = explode("/", $this->aAttributes['gps']['GPSLatitude'][1]);
165 | $latThird = explode("/", $this->aAttributes['gps']['GPSLatitude'][2]);
166 | $latRef = isset($this->aAttributes['gps']['GPSLatitudeRef']) ? $this->aAttributes['gps']['GPSLatitudeRef'] : 'N';
167 |
168 | $latFirst = intval($latFirst[0]) / intval($latFirst[1]);
169 | $latSecond = intval($latSecond[0])/ intval($latSecond[1]);
170 | $latThird = intval($latThird[0]) / intval($latThird[1]);
171 |
172 | $dLat = $latFirst + ($latSecond*60 + $latThird) / 3600;
173 | if ($latRef == 'S')
174 | $dLat *= -1;
175 |
176 | $longFirst = explode("/", $this->aAttributes['gps']['GPSLongitude'][0]);
177 | $longSecond = explode("/", $this->aAttributes['gps']['GPSLongitude'][1]);
178 | $longThird = explode("/", $this->aAttributes['gps']['GPSLongitude'][2]);
179 | $longRef = isset($this->aAttributes['gps']['GPSLongitudeRef']) ? $this->aAttributes['gps']['GPSLongitudeRef'] : 'E';
180 |
181 | $longFirst = intval($longFirst[0]) / intval($longFirst[1]);
182 | $longSecond = intval($longSecond[0])/ intval($longSecond[1]);
183 | $longThird = intval($longThird[0]) / intval($longThird[1]);
184 |
185 | $dLong = $longFirst + ($longSecond*60 + $longThird) / 3600;
186 | if ($longRef == 'W')
187 | $dLat *= -1;
188 | }
189 | public function getGPSArray() {
190 | $dLat = 0.0; $dLong = 0.0;
191 | $this->getGPS($dLat, $dLong);
192 | return array('lat' => $dLat, 'long' => $dLong);
193 | }
194 |
195 | public function hasOrientation() {
196 | return isset($this->aAttributes['orientation']);
197 | }
198 | public function getOrientation() {
199 | switch($this->aAttributes['orientation']) {
200 | case 3:
201 | return 180;
202 | break;
203 | case 6:
204 | return -90;
205 | break;
206 | case 8:
207 | return 90;
208 | break;
209 | default:
210 | return 0;
211 | }
212 | }
213 | public function getRawOrientation() {
214 | return $this->aAttributes['orientation'];
215 | }
216 |
217 | }
218 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Hauke Schade
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/readme.markdown:
--------------------------------------------------------------------------------
1 | # Image-Metadata-Parser
2 |
3 | Hi! Image-Metadata-Parser is a set of php function which try to simplify the access to some imagefiles metadata (exif, itpc or xmp).
4 |
5 | ## Usage
6 |
7 | To use Image-Metadata-Parser, you simply need to place the class somewhere accessible within your application.
8 |
9 | Then you can create a new ParserObject with some imagefile and read its metadata.
10 |
11 | parseExif())
16 | echo "Parsing of Exif Data failed";
17 | if (!$imageparser->parseIPTC())
18 | echo "Parsing of IPTC failed";
19 |
20 | Get the title
21 |
22 | if ($imageparser->hasTitle())
23 | echo "Image Title: " . $imageparser->getTitle();
24 |
25 | get the date and time
26 |
27 | if ($imageparser->hasDateTime())
28 | echo "Image Taken At: " . date('r', $imageparser->getDateTime());
29 |
30 | get a thumbnail
31 |
32 | if ($imageparser->hasThumbnail()) {
33 | echo "";
38 | }
39 |
40 | check the orientation
41 |
42 | if ($imageparser->hasOrientation())
43 | if ($imageparser->getOrientation() === 0)
44 | echo "Image is oriented properly.
\n";
45 | else
46 | echo "Image needs to be rotated with imagerotate(image, " . $imageparser->getOrientation() . ", 0);
\n";
47 |
48 | get the gps coordinates
49 |
50 | if ($imageparser->hasGPS()) {
51 | $dLat = 0; $dLong = 0;
52 | $imageparser->getGPS($dLat, $dLong);
53 | echo "approximate GPS position: " .
54 | "Lat: " . $dLat . " Long: " . $dLong . "";
55 | }
56 |
57 | Hope you find it useful! :)
58 |
--------------------------------------------------------------------------------
/test/test.php:
--------------------------------------------------------------------------------
1 |
imagerotate(image, " . $imageparser->getOrientation() . ", 0);