[ Index ] |
|
Code source de Dotclear 2.0-beta6 |
1 <?php 2 # ***** BEGIN LICENSE BLOCK ***** 3 # This file is part of Clearbricks. 4 # Copyright (c) 2006 Olivier Meunier and contributors. All rights 5 # reserved. 6 # 7 # Clearbricks is free software; you can redistribute it and/or modify 8 # it under the terms of the GNU General Public License as published by 9 # the Free Software Foundation; either version 2 of the License, or 10 # (at your option) any later version. 11 # 12 # Clearbricks is distributed in the hope that it will be useful, 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # GNU General Public License for more details. 16 # 17 # You should have received a copy of the GNU General Public License 18 # along with Clearbricks; if not, write to the Free Software 19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 # 21 # ***** END LICENSE BLOCK ***** 22 # 23 # Contributors: 24 # - Mathieu Lecarme 25 26 class imageMeta 27 { 28 protected $meta = array(); 29 protected $xmp = array(); 30 protected $iptc = array(); 31 protected $exif = array(); 32 33 public static function readMeta($f) 34 { 35 $o = new self; 36 $o->loadFile($f); 37 return $o->getMeta(); 38 } 39 40 public function getMeta() 41 { 42 foreach ($this->properties as $k => $v) 43 { 44 if (!empty($this->xmp[$k])) { 45 $this->properties[$k] = $this->xmp[$k]; 46 } elseif (!empty($this->iptc[$k])) { 47 $this->properties[$k] = $this->iptc[$k]; 48 } elseif (!empty($this->exif[$k])) { 49 $this->properties[$k] = $this->exif[$k]; 50 } 51 } 52 53 # Fix date format 54 $this->properties['DateTimeOriginal'] = preg_replace( 55 '/^(\d{4}):(\d{2}):(\d{2})/','$1-$2-$3', 56 $this->properties['DateTimeOriginal'] 57 ); 58 59 return $this->properties; 60 } 61 62 public function loadFile($f) 63 { 64 if (!is_file($f) || !is_readable($f)) { 65 throw new Exception('Unable to read file'); 66 } 67 68 $this->readXMP($f); 69 $this->readIPTC($f); 70 $this->readExif($f); 71 } 72 73 protected function readXMP($f) 74 { 75 if (($fp = @fopen($f,'rb')) === false) { 76 throw new Exception('Unable to open image file'); 77 } 78 79 $inside = false; 80 $done = false; 81 $xmp = null; 82 83 while (!feof($fp)) 84 { 85 $buffer = fgets($fp,4096); 86 87 $xmp_start = strpos($buffer,'<x:xmpmeta'); 88 89 if ($xmp_start !== false) { 90 $buffer = substr($buffer,$xmp_start); 91 $inside = true; 92 } 93 94 if ($inside) 95 { 96 $xmp_end = strpos($buffer,'</x:xmpmeta>'); 97 if ($xmp_end !== false) { 98 $buffer = substr($buffer,$xmp_end,12); 99 $inside = false; 100 $done = true; 101 } 102 103 $xmp .= $buffer; 104 } 105 106 if ($done) { 107 break; 108 } 109 } 110 fclose($fp); 111 112 if (!$xmp) { 113 return; 114 } 115 116 foreach ($this->xmp_reg as $code => $patterns) 117 { 118 foreach ($patterns as $p) 119 { 120 if (preg_match($p,$xmp,$m)) { 121 $this->xmp[$code] = $m[1]; 122 break; 123 } 124 } 125 } 126 127 if (preg_match('%<dc:subject>\s*<rdf:Bag>(.+?)</rdf:Bag%msu',$xmp,$m) 128 && preg_match_all('%<rdf:li>(.+?)</rdf:li>%msu',$m[1],$m)) 129 { 130 $this->xmp['Keywords'] = implode(',',$m[1]); 131 } 132 133 foreach ($this->xmp as $k => $v) { 134 $this->xmp[$k] = html::decodeEntities(text::toUTF8($v)); 135 } 136 } 137 138 protected function readIPTC($file) 139 { 140 if (!function_exists('iptcparse')) { 141 return; 142 } 143 144 $imageinfo = null; 145 @getimagesize($file,$imageinfo); 146 147 if (!is_array($imageinfo) || !isset($imageinfo['APP13'])) { 148 return; 149 } 150 151 $iptc = @iptcparse($imageinfo['APP13']); 152 153 if (!is_array($iptc)) { 154 return; 155 } 156 157 foreach ($this->iptc_ref as $k => $v) 158 { 159 if (isset($iptc[$k]) && isset($this->iptc_to_property[$v])) { 160 $this->iptc[$this->iptc_to_property[$v]] = text::toUTF8(trim(implode(',',$iptc[$k]))); 161 } 162 } 163 } 164 165 protected function readEXIF($f) 166 { 167 if (!function_exists('exif_read_data')) { 168 return; 169 } 170 171 $d = @exif_read_data($f,'ANY_TAG'); 172 173 if (!is_array($d)) { 174 return; 175 } 176 177 foreach ($this->exif_to_property as $k => $v) 178 { 179 if (isset($d[$k])) { 180 $this->exif[$v] = text::toUTF8($d[$k]); 181 } 182 } 183 } 184 185 /* Properties 186 ------------------------------------------------------- */ 187 protected $properties = array( 188 'Title' => null, 189 'Description' => null, 190 'Creator' => null, 191 'Rights' => null, 192 'Make' => null, 193 'Model' => null, 194 'Exposure' => null, 195 'FNumber' => null, 196 'MaxApertureValue' => null, 197 'ExposureProgram' => null, 198 'ISOSpeedRatings' => null, 199 'DateTimeOriginal' => null, 200 'ExposureBiasValue' => null, 201 'MeteringMode' => null, 202 'FocalLength' => null, 203 'Lens' => null, 204 'CountryCode' => null, 205 'Country' => null, 206 'State' => null, 207 'City' => null, 208 'Keywords' => null 209 ); 210 211 # XMP 212 protected $xmp_reg = array( 213 'Title' => array( 214 '%<dc:title>\s*<rdf:Alt>\s*<rdf:li.*?>(.+?)</rdf:li>%msu' 215 ), 216 'Description' => array( 217 '%<dc:description>\s*<rdf:Alt>\s*<rdf:li.*?>(.+?)</rdf:li>%msu' 218 ), 219 'Creator' => array( 220 '%<dc:creator>\s*<rdf:Seq>\s*<rdf:li>(.+?)</rdf:li>%msu' 221 ), 222 'Rights' => array( 223 '%<dc:rights>\s*<rdf:Alt>\s*<rdf:li.*?>(.+?)</rdf:li>%msu' 224 ), 225 'Make' => array( 226 '%<tiff:Make>(.+?)</tiff:Make>%msu', 227 '%tiff:Make="(.+?)"%msu' 228 ), 229 'Model' => array( 230 '%<tiff:Model>(.+?)</tiff:Model>%msu', 231 '%tiff:Model="(.+?)"%msu' 232 ), 233 'Exposure' => array( 234 '%<exif:ExposureTime>(.+?)</exif:ExposureTime>%msu', 235 '%exif:ExposureTime="(.+?)"%msu' 236 ), 237 'FNumber' => array( 238 '%<exif:FNumber>(.+?)</exif:FNumber>%msu', 239 '%exif:FNumber="(.+?)"%msu' 240 ), 241 'MaxApertureValue' => array( 242 '%<exif:MaxApertureValue>(.+?)</exif:MaxApertureValue>%msu', 243 '%exif:MaxApertureValue="(.+?)"%msu' 244 ), 245 'ExposureProgram' => array( 246 '%<exif:ExposureProgram>(.+?)</exif:ExposureProgram>%msu', 247 '%exif:ExposureProgram="(.+?)"%msu' 248 ), 249 'ISOSpeedRatings' => array( 250 '%<exif:ISOSpeedRatings>\s*<rdf:Seq>\s*<rdf:li>(.+?)</rdf:li>%msu' 251 ), 252 'DateTimeOriginal' => array( 253 '%<exif:DateTimeOriginal>(.+?)</exif:DateTimeOriginal>%msu', 254 '%exif:DateTimeOriginal="(.+?)"%msu' 255 ), 256 'ExposureBiasValue' => array( 257 '%<exif:ExposureBiasValue>(.+?)</exif:ExposureBiasValue>%msu', 258 '%exif:ExposureBiasValue="(.+?)"%msu' 259 ), 260 'MeteringMode' => array( 261 '%<exif:MeteringMode>(.+?)</exif:MeteringMode>%msu', 262 '%exif:MeteringMode="(.+?)"%msu' 263 ), 264 'FocalLength' => array( 265 '%<exif:FocalLength>(.+?)</exif:FocalLength>%msu', 266 '%exif:FocalLength="(.+?)"%msu' 267 ), 268 'Lens' => array( 269 '%<aux:Lens>(.+?)</aux:Lens>%msu', 270 '%aux:Lens="(.+?)"%msu' 271 ), 272 'CountryCode' => array( 273 '%<Iptc4xmpCore:CountryCode>(.+?)</Iptc4xmpCore:CountryCode>%msu', 274 '%Iptc4xmpCore:CountryCode="(.+?)"%msu' 275 ), 276 'Country' => array( 277 '%<photoshop:Country>(.+?)</photoshop:Country>%msu', 278 '%photoshop:Country="(.+?)"%msu' 279 ), 280 'State' => array( 281 '%<photoshop:State>(.+?)</photoshop:State>%msu', 282 '%photoshop:State="(.+?)"%msu' 283 ), 284 'City' => array( 285 '%<photoshop:City>(.+?)</photoshop:City>%msu', 286 '%photoshop:City="(.+?)"%msu' 287 ) 288 ); 289 290 # IPTC 291 protected $iptc_ref = array( 292 '1#090' => 'Iptc.Envelope.CharacterSet',// Character Set used (32 chars max) 293 '2#005' => 'Iptc.ObjectName', // Title (64 chars max) 294 '2#015' => 'Iptc.Category', // (3 chars max) 295 '2#020' => 'Iptc.Supplementals', // Supplementals categories (32 chars max) 296 '2#025' => 'Iptc.Keywords', // (64 chars max) 297 '2#040' => 'Iptc.SpecialsInstructions', // (256 chars max) 298 '2#055' => 'Iptc.DateCreated', // YYYYMMDD (8 num chars max) 299 '2#060' => 'Iptc.TimeCreated', // HHMMSS+/-HHMM (11 chars max) 300 '2#062' => 'Iptc.DigitalCreationDate', // YYYYMMDD (8 num chars max) 301 '2#063' => 'Iptc.DigitalCreationTime', // HHMMSS+/-HHMM (11 chars max) 302 '2#080' => 'Iptc.ByLine', // Author (32 chars max) 303 '2#085' => 'Iptc.ByLineTitle', // Author position (32 chars max) 304 '2#090' => 'Iptc.City', // (32 chars max) 305 '2#092' => 'Iptc.Sublocation', // (32 chars max) 306 '2#095' => 'Iptc.ProvinceState', // (32 chars max) 307 '2#100' => 'Iptc.CountryCode', // (32 alpha chars max) 308 '2#101' => 'Iptc.CountryName', // (64 chars max) 309 '2#105' => 'Iptc.Headline', // (256 chars max) 310 '2#110' => 'Iptc.Credits', // (32 chars max) 311 '2#115' => 'Iptc.Source', // (32 chars max) 312 '2#116' => 'Iptc.Copyright', // Copyright Notice (128 chars max) 313 '2#118' => 'Iptc.Contact', // (128 chars max) 314 '2#120' => 'Iptc.Caption', // Caption/Abstract (2000 chars max) 315 '2#122' => 'Iptc.CaptionWriter' // Caption Writer/Editor (32 chars max) 316 ); 317 318 protected $iptc_to_property = array( 319 'Iptc.ObjectName' => 'Title', 320 'Iptc.Caption' => 'Description', 321 'Iptc.ByLine' => 'Creator', 322 'Iptc.Copyright' =>'Rights', 323 'Iptc.CountryCode' => 'CountryCode', 324 'Iptc.CountryName' => 'Country', 325 'Iptc.ProvinceState' => 'State', 326 'Iptc.City' => 'City', 327 'Iptc.Keywords' => 'Keywords' 328 ); 329 330 # EXIF 331 protected $exif_to_property = array( 332 //'' => 'Title', 333 'ImageDescription' => 'Description', 334 'Artist' => 'Creator', 335 'Copyright' => 'Rights', 336 'Make' => 'Make', 337 'Model' => 'Model', 338 'ExposureTime' => 'Exposure', 339 'FNumber' => 'FNumber', 340 'MaxApertureValue' => 'MaxApertureValue', 341 'ExposureProgram' => 'ExposureProgram', 342 'ISOSpeedRatings' => 'ISOSpeedRatings', 343 'DateTimeOriginal' => 'DateTimeOriginal', 344 'ExposureBiasValue' => 'ExposureBiasValue', 345 'MeteringMode' => 'MeteringMode', 346 'FocalLength' => 'FocalLength' 347 //'' => 'Lens', 348 //'' => 'CountryCode', 349 //'' => 'Country', 350 //'' => 'State', 351 //'' => 'City', 352 //'' => 'Keywords' 353 ); 354 } 355 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Feb 23 22:16:06 2007 | par Balluche grâce à PHPXref 0.7 |