horst Posted July 18, 2016 Share Posted July 18, 2016 Metadata Exif Version 0.9.0 (currently a WIP) for PW 2.8.+ / 3.0+ This is a new attempt to add easy EXIF reading support to ProcessWire. It should be an easy and less error prone API task. Thats why the module internally uses lowercase key names for all EXIF keys and all of your requested key names. But you are not forced to use lowercase key names, you can use any mixed chars for it as you like. You will get back an array or object with keynames / properties named the same (casesensitive) way as you have passed them in with your request. API The module adds one hook to the Pageimage: getExif($options = null) Without any $options passed to the method, it returns all EXIF data in a RAW multidim array. Passing a simple list with requested key names as array to it returns an array with only the values of those requested keynames. If you want change the output from array to object, you can use the a boolean "toObject" set to true. Additionally to this and / or any other option, you need to put your requested keynames list to the option "keys". $rawArray = $image->getExif(); $options = array('Whitebalance', 'Flash', 'ISOSpeedRatings', 'FNumber', 'UserComment'); $array = $image->getExif($options); $options = array('toObject' => true, 'keys' => array('whitebalance', 'flash', 'isospeedratings', 'fnumber', 'usercomment')); $object = $image->getExif($options); Possible options are Quote keys = array, a list with case insensitive keynames thumbnail = bool, you can set thumbnail explicitly as own option, or you can add thumbnail as keyname to keys toObject = bool, if is false or missing, an array is returned unformatted = bool, if explicitly set to true, you will get back unformatted (raw) values returnRaw = bool, when no $options are set, or no $options['keys'] are set, or explicitly this param is set to true, the complete RAW EXIF data is returned A working example $options = array( 'keys' => array('ISOSpeedRatings', 'FNumber', 'Flash') ); echo "<table><tr>"; foreach($options['keys'] as $key) echo "<th>{$key}</th>"; echo "</tr>"; foreach($page->images as $image) { $exif = $image->getExif($options); echo "<tr>"; foreach($exif as $value) echo "<td>$value</td>"; echo "</tr>"; } echo "</table>"; This will output something like: Quote ISOSpeedRatings FNumber Flash 320 f/2.2 Flash did not fire, compulsory flash mode 100 f/4.0 Flash did not fire, compulsory flash mode With the boolean option "unformatted" passed as true, the output would look like: Quote ISOSpeedRatings FNumber Flash 320 11/5 16 100 40/10 16 For some keys, that only store something like integer values, what are not very meaningful to most of us, the module contain xyzFormatted methods. This way, it is easy to enhance and maintain the module in the future. Help wanted It would be nice if some of you test the module and report back if the intended API suites your needs. And you are very welcome to post suggestions for which keys you want to have a ...Formatted method. Thank you! https://github.com/horst-n/MetadataExif 12 Link to comment Share on other sites More sharing options...
JasonS Posted November 27, 2017 Share Posted November 27, 2017 Hi, Thanks for the great module. I'm trying to use this for a single image, however, i'm unable to get this to work for just the first image in multi-image field. Link to comment Share on other sites More sharing options...
horst Posted November 27, 2017 Author Share Posted November 27, 2017 how does your code look like for getting the (first) image from your field and getting the exif information? Link to comment Share on other sites More sharing options...
JasonS Posted November 27, 2017 Share Posted November 27, 2017 echo $page->galleryimages->first()->getExif('FNumber'); Link to comment Share on other sites More sharing options...
horst Posted November 27, 2017 Author Share Posted November 27, 2017 and what is the outcome? can you try var_dump($page->galleryimages->first()->getExif('FNumber')); Link to comment Share on other sites More sharing options...
JasonS Posted November 27, 2017 Share Posted November 27, 2017 Blank, nothing is returned. Link to comment Share on other sites More sharing options...
JasonS Posted November 27, 2017 Share Posted November 27, 2017 5 minutes ago, horst said: var_dump($page->galleryimages->first()->getExif('FNumber')); returns NULL Link to comment Share on other sites More sharing options...
horst Posted November 27, 2017 Author Share Posted November 27, 2017 var_dump(count($page->galleryimages)); $image = $page->galleryimages->first(); var_dump($image->url); var_dump($image->getExif()); please verify that: your field has at least one image that the image is of type jpeg that it (the original version) contains EXIF-data that it contain an entry FNumber Link to comment Share on other sites More sharing options...
JasonS Posted November 27, 2017 Share Posted November 27, 2017 1 minute ago, horst said: please verify that: your field has at least one image that the image is of type jpeg that it (the original version) contains EXIF-data that it contain an entry FNumber Yes I can confirm all of this. The multi-image field has two images. Using your example array from the first post of this thread I can see Exif information being returned for both. Both files are jpg type files. See array information returned from your working example code below. Link to comment Share on other sites More sharing options...
JasonS Posted November 27, 2017 Share Posted November 27, 2017 17 minutes ago, horst said: var_dump(count($page->galleryimages)); returns - int(2) Quote $image = $page->galleryimages->first(); Returns - nothing. Quote var_dump($page->galleryimages->url); returns - string(36) "/photography/site/assets/files/1031/" Quote var_dump($page->galleryimages->getExif()); returns - array(2) { ["apc_0046.jpg"]=> NULL ["img_0335.jpg"]=> NULL } Link to comment Share on other sites More sharing options...
horst Posted November 27, 2017 Author Share Posted November 27, 2017 your url does not contain an image name, it only points to the folder. and the last var_dump should get the EXIf from the single image, not from the image collection!! Link to comment Share on other sites More sharing options...
JasonS Posted November 27, 2017 Share Posted November 27, 2017 Quote var_dump($page->galleryimages->first()->getExif()); Notice: Undefined offset: 0 in /Applications/XAMPP/xamppfiles/htdocs/photography/site/modules/MetadataExif/MetadataExif.module on line 44array(5) { ["FILE"]=> array(6) { ["FileName"]=> string(12) "apc_0046.jpg" ["FileDateTime"]=> int(1511813872) ["FileSize"]=> int(1160717) ["FileType"]=> int(2) ["MimeType"]=> string(10) "image/jpeg" ["SectionsFound"]=> string(30) "ANY_TAG, IFD0, THUMBNAIL, EXIF" } ["COMPUTED"]=> array(9) { ["html"]=> string(26) "width="2797" height="3496"" ["Height"]=> int(3496) ["Width"]=> int(2797) ["IsColor"]=> int(1) ["ByteOrderMotorola"]=> int(0) ["ApertureFNumber"]=> string(5) "f/2.2" ["Copyright"]=> string(20) "photography" ["Thumbnail.FileType"]=> int(2) ["Thumbnail.MimeType"]=> string(10) "image/jpeg" } ["IFD0"]=> array(10) { ["ImageDescription"]=> string(36) "time flies" ["Make"]=> string(5) "Apple" ["Model"]=> string(14) "iPhone 6s Plus" ["XResolution"]=> string(5) "240/1" ["YResolution"]=> string(5) "240/1" ["ResolutionUnit"]=> int(2) ["Software"]=> string(49) "Adobe Photoshop Lightroom Classic 7.0 (Macintosh)" ["DateTime"]=> string(19) "2017:11:27 16:17:21" ["Copyright"]=> string(20) "j.sobers.photography" ["Exif_IFD_Pointer"]=> int(302) } ["THUMBNAIL"]=> array(6) { ["Compression"]=> int(6) ["XResolution"]=> string(4) "72/1" ["YResolution"]=> string(4) "72/1" ["ResolutionUnit"]=> int(2) ["JPEGInterchangeFormat"]=> int(896) ["JPEGInterchangeFormatLength"]=> int(17303) } ["EXIF"]=> array(26) { ["ExposureTime"]=> string(6) "1/2400" ["FNumber"]=> string(5) "22/10" ["ExposureProgram"]=> int(2) ["ISOSpeedRatings"]=> int(25) ["ExifVersion"]=> string(4) "0230" ["DateTimeOriginal"]=> string(19) "2017:07:10 11:47:22" ["DateTimeDigitized"]=> string(19) "2017:07:10 11:47:22" ["ShutterSpeedValue"]=> string(16) "11228819/1000000" ["ApertureValue"]=> string(15) "2275007/1000000" ["BrightnessValue"]=> string(8) "8488/781" ["ExposureBiasValue"]=> string(3) "0/1" ["MeteringMode"]=> int(5) ["Flash"]=> int(16) ["FocalLength"]=> string(5) "83/20" ["SubjectLocation"]=> array(4) { [0]=> int(2015) [1]=> int(1511) [2]=> int(2217) [3]=> int(1330) } ["SubSecTimeOriginal"]=> string(3) "208" ["SubSecTimeDigitized"]=> string(3) "208" ["ColorSpace"]=> int(1) ["SensingMethod"]=> int(2) ["SceneType"]=> string(1) "" ["ExposureMode"]=> int(0) ["WhiteBalance"]=> int(0) ["FocalLengthIn35mmFilm"]=> int(29) ["UndefinedTag:0xA432"]=> array(4) { [0]=> string(5) "83/20" [1]=> string(5) "83/20" [2]=> string(4) "11/5" [3]=> string(4) "11/5" } ["UndefinedTag:0xA433"]=> string(5) "Apple" ["UndefinedTag:0xA434"]=> string(39) "iPhone 6s Plus back camera 4.15mm f/2.2" } } Quote var_dump($page->galleryimages->first()->url); string(48) "/photography/site/assets/files/1031/apc_0046.jpg" Sorry about that, i corrected my mistake. see above. Link to comment Share on other sites More sharing options...
horst Posted November 27, 2017 Author Share Posted November 27, 2017 Sorry, now I see that you are using a single value string as $options. This is not possible. Please refer to the examples above: you need to pass an array to the function, also if you want to retrieve a single value: $image->getExif( array('FNumber') ); Link to comment Share on other sites More sharing options...
JasonS Posted November 27, 2017 Share Posted November 27, 2017 Quote echo $page->galleryimages->first()->getExif( array('FNumber') ); Returned : Quote Notice: Array to string conversion in /Applications/XAMPP/xamppfiles/htdocs/photography/site/templates/clientgallery.php on line 9Array Link to comment Share on other sites More sharing options...
horst Posted November 28, 2017 Author Share Posted November 28, 2017 you need to echo out your desired array key, or object property, depending on what you choosed. You choosed an array for the return, therefore you need to output the key "FNumber" of the array: $result = $page->galleryimages->first()->getExif( array('FNumber') ); // output the value for one key of the returned array echo $result['FNumber']; // if you have choosen the result as object, you would use echo $result->FNumber; This all you can read in the initial post of this thread. 1 Link to comment Share on other sites More sharing options...
JasonS Posted November 29, 2017 Share Posted November 29, 2017 Hi Horst, With your instructions and help, I got it to work. Thanks again for working with me in understanding proper methods for rendering the values I needed. For Future reference for anyone else(including myself if I forget )... There are two methods for rendering data from Metadata EXIF module. Array Method: // output the value for one key of the returned array $firstGalleryImage = $page->galleryimages->first()->getExif( array('FNumber') ); echo $firstGalleryImage['FNumber']; Object Method: // if you have choosen the result as object, you would use $options = array('toObject' => true, 'keys' => array('FNumber')); $object = $page->galleryimages->first()->getExif($options); echo $object->FNumber; 1 1 Link to comment Share on other sites More sharing options...
Robin S Posted December 19, 2019 Share Posted December 19, 2019 Hi @horst, Thanks for this module! It would be great if the module alerted the user somehow if the required PHP exif extension is not installed. I spent some time trying to work out why I couldn't get any data back from images and it wasn't until I saw this in the module code... if(!function_exists('exif_read_data')) return null; ...that I realised my local WAMP stack didn't have the exif extension enabled. Link to comment Share on other sites More sharing options...
horst Posted December 19, 2019 Author Share Posted December 19, 2019 10 hours ago, Robin S said: It would be great if the module alerted the user somehow if the required PHP exif extension is not installed. What do you think would be the best way? Returning false or throwing an exception? Link to comment Share on other sites More sharing options...
Robin S Posted December 19, 2019 Share Posted December 19, 2019 7 hours ago, horst said: Returning false or throwing an exception? I think the getExif() method should throw an exception if the module requirements aren't met. But the module could also check for this when it's installed. Unfortunately I don't think it's possible to include PHP extensions in the "requires" item of getModuleInfo() but the Module documentation says (after correcting typo): Quote If the install() method determines that the module cannot be installed for some reason, it should throw a WireException. So the install method could be this: public function ___install() { if(!function_exists('exif_read_data')) { throw new WireException('MetadataExif requires the PHP exif extension.'); }; } Link to comment Share on other sites More sharing options...
horst Posted December 19, 2019 Author Share Posted December 19, 2019 Many thanks for the suggestions, @Robin S I think the main check / exception must be in the getExif method. A check during install will be useless when deploying a site folder from local to stage or live. But it is no harm to have it too. ? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now