Rev 1181 | Rev 1198 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?phpclass MigrationImages extends Cel {public static $bdd_cel_migration;public static $bdd_utilisateurs;const truncate = true; //Doit on vider les tables de destination ?const separateur_champs_metadonnees = ';';const separateur_valeurs_metadonnees = ':';private $id_cle_metadonnees = array();/** Tableau associatif permettant de stocker l'avancement dans une boucle.* La clé est un md5 du message à afficher au démarrage de la boucle.* @var array*/private static $avancement = array();const dry_run = false;private $tableau_utilisateurs = array();private $tableau_observations = array();private $tableau_mots_cles = array();private $tableau_nouveau_ancien = array('id_image' => 'ci_id_image','ordre' =>'ci_ordre','ce_utilisateur' => 'traiterIdentifiantUtilisateur','prenom_utilisateur' => 'traiterPrenomUtilisateur','nom_utilisateur' => 'traiterNomUtilisateur','courriel_utilisateur' => 'ci_ce_utilisateur','hauteur' => 'ci_meta_height','largeur' => 'ci_meta_width','appareil_fabriquant' => 'ci_meta_make','appareil_modele' => 'ci_meta_model','date_prise_de_vue' => 'ci_meta_date_time','note_qualite' => 'ci_note_image','mots_cles_texte' => 'traiterMotsClesTexte','commentaire' => 'ci_meta_comment','nom_original' => 'ci_nom_original','md5' => 'ci_md5','meta_exif' => 'traiterExif','meta_iptc' => 'traiterIptc','meta_xmp' => 'traiterXmp','meta_makernote' => 'traiterMakernote','date_modification' => 'ci_meta_date','date_creation' => 'ci_meta_date_ajout');private $champs_exifs_non_gardes = array('ci_meta_x_resolution','ci_meta_y_resolution','ci_meta_gps','ci_meta_user_comment','ci_meta_exif_exposure_time','ci_meta_exif_f_number','ci_meta_exif_exif_version','ci_meta_exif_compressed_bits_per_pixel','ci_meta_exif_shutter_speed_value','ci_meta_exif_aperture_value','ci_meta_exif_exposure_bias_value','ci_meta_exif_max_aperture_value','ci_meta_exif_metering_mode','ci_meta_exif_light_source','ci_meta_exif_flash','ci_meta_exif_focal_length','ci_meta_exif_flash_pix_version','ci_meta_exif_color_space','ci_meta_exif_interoperability_offset','ci_meta_exif_focal_plane_x_resolution','ci_meta_exif_focal_plane_y_resolution','ci_meta_exif_focal_plane_resolution_unit','ci_meta_exif_sensing_method','ci_meta_exif_file_source','ci_meta_exif_custom_rendered','ci_meta_exif_exposure_mode','ci_meta_exif_white_balance','ci_meta_exif_digital_zoom_ratio','ci_meta_exif_scene_capture_type','ci_meta_exif_gain_control','ci_meta_exif_contrast','ci_meta_exif_saturation','ci_meta_exif_sharpness','ci_meta_exif_subject_distance_range');private $champs_iptc_non_gardes = array('ci_meta_iptc_category','ci_meta_iptc_by_line','ci_meta_iptc_by_line_title','ci_meta_iptc_city','ci_meta_iptc_sub_location','ci_meta_iptc_province_state','ci_meta_iptc_country_primary_location_code','ci_meta_iptc_country_name','ci_meta_iptc_headline','ci_meta_iptc_credit','ci_meta_iptc_copyright_notice','ci_meta_iptc_contact');private $champs_divers_non_gardes = array('ci_publiable_eflore','ci_meta_mots_cles');/*** Utiliser cette méthode dans une boucle pour afficher un message suivi du nombre de tour de boucle effectué.* Vous devrez vous même gérer le retour à la ligne à la sortie de la boucle.** @param string le message d'information.* @param int le nombre de départ à afficher.* @return void le message est affiché dans la console.*/protected function afficherAvancement($message, $depart = 0) {if (! isset(self::$avancement[$message])) {self::$avancement[$message] = $depart;echo "$message : ";$actuel =& self::$avancement[$message];echo $actuel++;} else {$actuel =& self::$avancement[$message];// Cas du passage de 99 (= 2 caractères) à 100 (= 3 caractères)$passage = 0;if (strlen((string) ($actuel - 1)) < strlen((string) ($actuel))) {$passage = 1;}echo str_repeat(chr(8), (strlen((string) $actuel) - $passage));echo $actuel++;}}/*** Méthode appelée avec une requête de type GET.*/public function getElement($params) {if(!isset($this->config['database_cel']['database_migration']) || $this->config['database_cel']['database_migration'] == '') {echo 'Attention la variable de configuration database_migration dans la section database_cel, contenant la base de données d\'arrivée, doit être remplie '."\n";exit;}if(!isset($this->config['database_ident']['database']) || $this->config['database_ident']['database'] == '') {echo 'Attention la variable de configuration database dans la section database_ident, contenant la base de données utilisateurs, doit être remplie '."\n";exit;}self::$bdd_cel_migration = $this->config['database_cel']['database_migration'];self::$bdd_utilisateurs = $this->config['database_ident']['database'];$this->id_cle_metadonnees = array_merge($this->tableau_ids_tags_exif, $this->tableau_ids_tags_iptc);echo "--MIGRATION DES IMAGES --------------------------------------\n";//1. TEMPORAIRE : vider les tables de destinationsif (self::truncate) {echo "-------------------------------------------------------------------\n\n";echo " ETAPE 0. Vider les tables ... \n\n";echo "-------------------------------------------------------------------\n\n";$nouvellesTables = array('cel_images', 'cel_obs_images');foreach ($nouvellesTables as $nomTable) {echo 'Vider la table '.$nomTable.'...';$requeteTruncate = 'TRUNCATE TABLE '.self::$bdd_cel_migration.'.'.$nomTable;$resultatTruncate = $this->executerRequete($requeteTruncate);echo "ok \n";}echo "\n---------------------------------------------------------------- OK\n\n";}echo "-------------------------------------------------------------------\n\n";echo " ETAPE 1. Paramétrage ... \n\n";echo "-------------------------------------------------------------------\n\n";$this->getUtilisateurs();$this->getMotsCles();$this->getObservations();echo "-------------------------------------------------------------------\n\n";echo " ETAPE 2. Migration des images ... \n\n";echo "-------------------------------------------------------------------\n\n";$this->migrerImages();echo "\n"."\n"."\n";echo "-------------------------------------------------------------------\n\n";echo " ETAPE 3. migration des liaisons obs images ... \n\n";echo "-------------------------------------------------------------------\n\n";$this->migrerLiaisonsObsImages();echo "\n"."\n"."\n";}private function getUtilisateurs() {echo "\n-------------------------------------------------------------------\n";echo "--SELECTION DES UTILISATEURS---------------------------------------\n\n";$requete_selection_utilisateurs = 'SELECT U_ID as id, U_MAIL as mail, U_NAME as nom, U_SURNAME as prenom, U_PASSWD as pass FROM '.self::$bdd_utilisateurs.'.annuaire_tela';$tableau_utilisateurs = $this->executerRequete($requete_selection_utilisateurs);foreach( $tableau_utilisateurs as &$utilisateur) {$this->tableau_utilisateurs[$utilisateur['mail']] = $utilisateur;}echo sizeof($this->tableau_utilisateurs)." utilisateurs sélectionnés";echo "\n-----------------------------------------------------------------OK\n";}private function getMotsCles() {echo "\n-------------------------------------------------------------------\n";echo "--SELECTION DES MOTS-CLES -----------------------------------------\n\n";$requete_selection_mots_cles = 'SELECT cmc_id_proprietaire as id_utilisateur, cmc_id_mot_cle_utilisateur as id_mot_cle, cmc_mot_cle as mot_cle FROM cel_mots_cles_obs';$tableau_mots_cles = $this->executerRequete($requete_selection_mots_cles);foreach( $tableau_mots_cles as &$mot_cle) {$this->tableau_mots_cles[$mot_cle['id_utilisateur']][$mot_cle['id_mot_cle']] = $mot_cle;}echo sizeof($this->tableau_mots_cles)." mots-clés sélectionnés";echo "\n-----------------------------------------------------------------OK\n";}private function getObservations() {$pas = 5000;$nObs = "SELECT COUNT(*) AS nb FROM cel_inventory";$resultatNbObs = $this->executerRequete($nObs);$nbObs = $resultatNbObs[0]['nb'];for ($i = 0; $i < 230000; $i += $pas ) {$requete_selection_observations = 'SELECT id, ordre, identifiant FROM cel_inventory LIMIT '.$i.", $pas";$tableau_observations = $this->executerRequete($requete_selection_observations);foreach($tableau_observations as &$obs) {$this->tableau_observations[$obs['identifiant']][$obs['ordre']] = $obs['id'];}$this->afficherAvancement('Selection des observations (par '.$pas.' )', $nbObs);}echo "\n\n";}public function executerRequeteSimple($requete) {// Fonction de commodité pour afficher les requetes au lieu de les executerif (self::dry_run) {echo str_replace('),','),'."\n", $requete)."\n";return true;} else {return parent::executerRequeteSimple($requete);}}private function migrerImages() {$debut = 0;$pas = 200;$fin = 150000;//Selectionner le nombre d'images$requeteNbImg = "SELECT COUNT(*) as nb FROM cel_images";$resultatNbImg = $this->executerRequete($requeteNbImg);$fin = $resultatNbImg[0]['nb'];for ($i = $debut; $i <= $fin ; $i += $pas) {$requete_selection_images = 'SELECT * FROM cel_images '.'ORDER BY ci_id_image ASC LIMIT '.$i.','.$pas;$images = @$this->requeter($requete_selection_images);$requete_insertion_images = 'INSERT INTO '.self::$bdd_cel_migration.'.cel_images (';foreach ($this->tableau_nouveau_ancien as $nouveau_champ => $ancien_champ) {$requete_insertion_images .= $nouveau_champ.',';}$requete_insertion_images = rtrim($requete_insertion_images, ',');$requete_insertion_images = $requete_insertion_images.') VALUES ';if (is_array($images)) {$nb_images_a_traiter = count($images);foreach($images as $image) {$nouvelle_image = $this->traiterLigneImage($image);$nouvelle_image = array_map(array($this,'proteger'),$nouvelle_image);$requete_insertion_images .= '('.join(',',array_values($nouvelle_image)).'),';}$requete_insertion_images = rtrim($requete_insertion_images, ',');$migration_images = $this->executer($requete_insertion_images);if (!$migration_images) {echo 'la migration des images '.$i.' à '.($i+$nb_images_a_traiter).' a échoué '."\n";} else {$this->afficherAvancement('Migration des images (par '.$pas.' )', $fin);}}if(count($images) < $pas) {echo "\n---------------------------------------------------------------- OK\n\n";return;}}}private function migrerLiaisonsObsImages() {$debut = 0;$pas = 500;$fin = 50000;$liaisons_obs_inexistantes = 0;//Selectionner le nombre de liaisons$requeteNbImgObs = "SELECT COUNT(*) as nb FROM cel_obs_images";$resultatNbImgObs = $this->executerRequete($requeteNbImgObs);$fin = $resultatNbImgObs[0]['nb'];for ($i = $debut; $i <= $fin ; $i += $pas) {if($i > $fin) {$i = $fin;}$requete_selection_liaisons = 'SELECT * FROM cel_obs_images LIMIT '.$i.','.$pas;$tableau_liaisons = $this->executerRequete($requete_selection_liaisons);$requete_migration_liaison = 'INSERT INTO '.self::$bdd_cel_migration.'.cel_obs_images '.'(id_image, id_utilisateur, id_observation, date_liaison) '.'VALUES ';$sous_requete_insertion = '';if(is_array($tableau_liaisons)) {foreach($tableau_liaisons as &$liaison) {$mail_utilisateur = $liaison['coi_ce_utilisateur'];$utilisateur = $this->renvoyerIdPourMigration($mail_utilisateur);$id_obs = $liaison['coi_ce_observation'];if (isset($this->tableau_observations[$mail_utilisateur][$id_obs])) {$id_obs = $this->tableau_observations[$mail_utilisateur][$id_obs];$sous_requete_insertion .= '('.$this->proteger($liaison['coi_ce_image']).','.$this->proteger($utilisateur).','.$this->proteger($id_obs).','.$this->proteger($liaison['coi_date_liaison']).'),';} else {// cas d'une observation inexistante, la liaison est ignorée$liaisons_obs_inexistantes++;}}$sous_requete_insertion = rtrim($sous_requete_insertion,',');$requete_migration_liaison = $requete_migration_liaison.$sous_requete_insertion;$migration_liaison = $this->executerRequeteSimple($requete_migration_liaison);if (!$migration_liaison) {echo 'la migration des liaisons obs images de '.$i.' à '.($i+$pas).' a échoué ! '."\n<br />";} else {$this->afficherAvancement('Migration des liaisons obs images (par '.$pas.' )', $fin);}}}echo "\n\n";echo $liaisons_obs_inexistantes ? $liaisons_obs_inexistantes." liaisons image obs ont été ignorées car les obs sont absentes" : '' ;echo "\n";echo "\n---------------------------------------------------------------- OK\n\n";}private function traiterLigneImage($image) {$nouvelle_image = array();foreach ($this->tableau_nouveau_ancien as $nouveau_champ_image => $ancien_champ_image) {if ($this->estUnChampATraiter($ancien_champ_image)) {if (method_exists($this,$ancien_champ_image)) {$nouvelle_image[$nouveau_champ_image] = $this->$ancien_champ_image($image);} else {echo 'methode manquante : '.$ancien_champ_image."\n";$nouvelle_image[$nouveau_champ_image] = '';}} else {$nouvelle_image[$nouveau_champ_image] = $image[$ancien_champ_image];}}return $nouvelle_image;}private function estUnChampATraiter($champ) {return strpos($champ, 'traiter') !== false;}private function traiterMotsClesTexte($ligne_image) {$mail_image = $ligne_image['ci_ce_utilisateur'];$retour = $ligne_image['ci_meta_mots_cles'];if (isset($this->tableau_mots_cles[$mail_image])) {$mots_cles_tableau = $this->parserMotsCles($mail_image, $ligne_image['ci_meta_mots_cles'], ',');$retour = join(';',$mots_cles_tableau);$retour = ltrim($retour,';;') ;}return $retour;}private function parserMotsCles($utilisateur, $mot_cles, $separateur = ',') {$tableau_mots_cles = explode($separateur,$mot_cles);$tableau_mots_cles_formates = array();foreach($tableau_mots_cles as $mot_cle) {$mot_cle = str_replace($separateur.$separateur,'',$mot_cle);$mot_cle = str_replace('null','',$mot_cle);if ($this->estUnIdentifiantMotCle($mot_cle)) {// certains mots clés mal formatés contiennent des virgulesif (strpos($mot_cle,',') !== false) {$tab_mot_cle_mal_formate = explode(',',$mot_cle);foreach ($tab_mot_cle_mal_formate as $mot_cle_mal_formate) {if ($this->estUnIdentifiantMotCle($mot_cle_mal_formate)) {$tableau_mots_cles_formates[$mot_cle_mal_formate] = $this->tableau_mots_cles[$utilisateur][$mot_cle_mal_formate]['mot_cle'];}}} else {// on met le mot clé dans sa propre case afin d'éviter// facilement les doublons provoqués par de mauvais formatagesif(isset($this->tableau_mots_cles[$utilisateur][$mot_cle])) {$tableau_mots_cles_formates[$mot_cle] = $this->tableau_mots_cles[$utilisateur][$mot_cle]['mot_cle'];}}}}return $tableau_mots_cles_formates;}private function estUnIdentifiantMotCle($chaine) {return trim($chaine) != '' && preg_match('/[0-9A-Z]+\.[0-9A-Z]+/i', $chaine) ;}private function traiterIdentifiantUtilisateur($ligne_image) {$mail_image = $ligne_image['ci_ce_utilisateur'];$retour = $this->renvoyerIdPourMigration($mail_image);return $retour;}private function traiterPrenomUtilisateur($ligne_image) {$mail_image = $ligne_image['ci_ce_utilisateur'];$retour = $mail_image;if (isset($this->tableau_utilisateurs[$mail_image])) {$retour = $this->tableau_utilisateurs[$mail_image]['prenom'];} else {$retour = '';}return $retour;}private function traiterNomUtilisateur($ligne_image) {$mail_image = $ligne_image['ci_ce_utilisateur'];$retour = $mail_image;if (isset($this->tableau_utilisateurs[$mail_image])) {$retour = $this->tableau_utilisateurs[$mail_image]['nom'];} else {$retour = '';}return $retour;}private function decoderTableauMetaDonnees($chaine) {$tableau_valeurs_decodees = array();if (trim($chaine) != '') {$tableau_meta = explode(self::separateur_champs_metadonnees,$chaine);foreach ($tableau_meta as &$chaine_meta) {$cle_valeur = explode(self::separateur_valeurs_metadonnees, $chaine_meta);if (is_array($cle_valeur) && count($cle_valeur) == 2) {$cle = ltrim($cle_valeur[0],' ');$tableau_valeurs_decodees[$cle] = $cle_valeur[1];}}}return $tableau_valeurs_decodees;}private function convertirTableauMetadonneesEnXml($tableau) {$xml = '';foreach($tableau as $cle => $valeur) {$cle = str_replace('ci_meta_exif_','',$cle);$cle = str_replace('ci_meta_iptc_','',$cle);$cle = str_replace('ci_meta_','',$cle);$cle = str_replace('_',' ',$cle);$cle = str_replace(' ','',ucwords($cle));$valeur = str_replace("\0",'',$valeur);$id = isset($this->id_cle_metadonnees[$cle]) ? $this->id_cle_metadonnees[$cle] : $cle;$xml .= '<'.$cle.' id="'.$id.'">'.$valeur.'</'.$cle.'>'."\n";}return $xml;}private function peutUtiliserExifTool() {return file_exists('/usr/bin/exiftool') && is_executable('/usr/bin/exiftool');}private function decoderMetadonnees($chemin_image) {$res = '';if($this->peutUtiliserExifTool()) {$res = $this->decoderMetadonneesExifTool($chemin_image);$xml_meta = '<?xml version="1.0" encoding="UTF-8" ?>';$xml_meta .= '<exif>';foreach($res['EXIF'] as $prop => $valeur) {$xml_meta .= ' <'.$prop.' id="'.$valeur['id'].'">'.$valeur['valeur'].'</'.$prop.'>'."\n";}$xml_meta .= '</exif>'."\n";$xml_meta .= '<iptc>';foreach($res['IPTC'] as $prop => $valeur) {$xml_meta .= ' <'.$prop.' id="'.$valeur['id'].'">'.$valeur['valeur'].'</'.$prop.'>'."\n";}$xml_meta .= '</iptc>'."\n";$xml_meta .= '<xmp>';foreach($res['XMP'] as $prop => $valeur) {$xml_meta .= ' <'.$prop.' id="'.$valeur['id'].'">'.$valeur['valeur'].'</'.$prop.'>'."\n";}$xml_meta .= '</xmp>'."\n";} else {}return $xml_meta;}private function decoderMetadonneesExifTool($chemin_image) {$metadata = array();$res = exec('/usr/bin/exiftool -g -D '.$chemin_image, $metadata);$metadata_decodees = array();$categorie = '';foreach($metadata as &$data) {if($this->estUnSeparateurCategorieExifTool($data)) {$categorie = trim(str_replace('----','',$data));} else {$data_decodee = $this->parserValeurMetadonneeExifTool($data);$cle_metadonnee = str_replace(' ', '', $data_decodee['cle']);$metadata_decodees[$categorie][$cle_metadonnee] = $data_decodee;$this->id_cle_metadonnees[$cle_metadonnee] = $data_decodee['id'];}}return $metadata_decodees;}private function estUnSeparateurCategorieExifTool($data) {return preg_match('^---- (.)* ----^',$data);}private function parserValeurMetadonneeExifTool($data) {$cle_valeur = explode(':',$data);$valeur = '';if(count($cle_valeur) == 2) {$valeur = trim($cle_valeur[1]);}$id_cle = explode(' ',trim($cle_valeur[0]),2);$id_cle[1] = str_replace(array('-','/'),'',$id_cle[1]);$cle_id_valeur = array('cle' => $id_cle[1], 'id' => str_replace('-','',$id_cle[0]), 'valeur' => $valeur);return $cle_id_valeur;}private function traiterExif($ligne_image) {$metadonnees_autres = $this->decoderTableauMetaDonnees($ligne_image['ci_meta_exif_autres']);$metadonnees = array_intersect_key($ligne_image, array_flip($this->champs_exifs_non_gardes))+$metadonnees_autres;$xml_meta = '<?xml version="1.0" encoding="UTF-8" ?>';$xml_meta .= '<exif>';$xml_meta .= $this->convertirTableauMetadonneesEnXml($metadonnees);$xml_meta .= '</exif>';return $xml_meta;}private function traiterIptc($ligne_image) {$metadonnees_autres = $this->decoderTableauMetaDonnees($ligne_image['ci_meta_iptc_autres']);$metadonnees = array_intersect_key($ligne_image, array_flip($this->champs_iptc_non_gardes))+$metadonnees_autres;$xml_meta = '<?xml version="1.0" encoding="UTF-8" ?>';$xml_meta .= '<iptc>';$xml_meta .= $this->convertirTableauMetadonneesEnXml($metadonnees);$xml_meta .= '</iptc>';return $xml_meta;}private function traiterXmp($ligne_image) {$chemin = $this->obtenirCheminImageOriginale($ligne_image['ci_id_image']);// TODO décommenté car pour le moment ça n'est pas necessaire, à éxécuter à part//$res = $this->decoderMetadonneesExifTool($chemin);$xml = '<?xml version="1.0" encoding="UTF-8" ?>';$xml .= '<xmp>';if (isset($res['XMP'])) {foreach ($res['XMP'] as $prop => $valeur) {$xml .= ' <'.$prop.' id="'.$valeur['id'].'">'.$valeur['valeur'].'</'.$prop.'>'."\n";}}$xml .= '</xmp>';return $xml;}private function traiterMakernote($ligne_image) {$chemin = $this->obtenirCheminImageOriginale($ligne_image['ci_id_image']);//$res = $this->decoderMetadonneesExifTool($chemin);$xml = '<?xml version="1.0" encoding="UTF-8" ?>';$xml .= '<makernote>';if (isset($res['MAKERNOTE'])) {foreach ($res['MAKERNOTE'] as $prop => $valeur) {$xml .= ' <'.$prop.' id="'.$valeur['id'].'">'.$valeur['valeur'].'</'.$prop.'>'."\n";}}$xml .= '</makernote>';return '';}public function obtenirCheminImageOriginale($id_image) {$nom = $this->convertirIdBddVersNomFichier($id_image, 'O');$dossier = $this->obtenirDossierPourFormat($id_image,'O');return $dossier.'/'.$nom;}public function convertirIdBddVersNomFichier($id, $format, $extension = 'jpg') {// creation du format original$id_avec_zeros = sprintf('%09s', $id) ;$id_avec_zeros_underscores = wordwrap($id_avec_zeros, 3 , '_', true) ;$nom_fichier = $id_avec_zeros_underscores.'_'.$format.'.'.$extension;return $nom_fichier;}public function obtenirDossierPourFormat($id, $format) {$chemin_base = $this->config['cel']['chemin_images'];$chemin_sur_serveur = $chemin_base;$id = sprintf('%09s', $id);$id = wordwrap($id, 3 , '_', true);list($dossierNiveau1, $dossierNiveau2) = explode('_', $id);$chemin_sur_serveur_final = $chemin_sur_serveur.'/'.$dossierNiveau1.'/'.$dossierNiveau2.'/'.$format;return $chemin_sur_serveur_final;}private function renvoyerIdPourMigration($utilisateur) {// si tout les test suivant échouent, on garde l'utilisateur tel quel// (cas de la chaine de session des utilisateur anonymes)$retour = $utilisateur;// si le mail correspond a un utilisateur de la bddif (isset($this->tableau_utilisateurs[$utilisateur])) {// on renvoie son id$retour = $this->tableau_utilisateurs[$utilisateur]['id'];} else {// sinon si c'est un mail inconnu, on garde le md5if($this->mailValide($utilisateur)) {$retour = md5($utilisateur);}}return $retour;}public function mailValide($mail) {// vérification bidon mais ça suffit pour icireturn !(strpos('@',$mail) === false);}private $tableau_ids_tags_exif = array('InteropIndex' => '1','InteropVersion' => '2','ProcessingSoftware' => '11','SubfileType' => '254','OldSubfileType' => '255','ImageWidth' => '256','ImageHeight' => '257','BitsPerSample' => '258','Compression' => '259','PhotometricInterpretation' => '262','Thresholding' => '263','CellWidth' => '264','CellLength' => '265','FillOrder' => '266','DocumentName' => '269','ImageDescription' => '270','Make' => '271','Model' => '272','StripOffsets' => '273','Orientation' => '274','SamplesPerPixel' => '277','RowsPerStrip' => '278','StripByteCounts' => '279','MinSampleValue' => '280','MaxSampleValue' => '281','XResolution' => '282','YResolution' => '283','PlanarConfiguration' => '284','PageName' => '285','XPosition' => '286','YPosition' => '287','FreeOffsets' => '288','FreeByteCounts' => '289','GrayResponseUnit' => '290','GrayResponseCurve' => '291','T4Options' => '292','T6Options' => '293','ResolutionUnit' => '296','PageNumber' => '297','ColorResponseUnit' => '300','TransferFunction' => '301','Software' => '305','ModifyDate' => '306','Artist' => '315','HostComputer' => '316','Predictor' => '317','WhitePoint' => '318','PrimaryChromaticities' => '319','ColorMap' => '320','HalftoneHints' => '321','TileWidth' => '322','TileLength' => '323','TileOffsets' => '324','TileByteCounts' => '325','BadFaxLines' => '326','CleanFaxData' => '327','ConsecutiveBadFaxLines' => '328','SubIFD' => '330','InkSet' => '332','InkNames' => '333','NumberofInks' => '334','DotRange' => '336','TargetPrinter' => '337','ExtraSamples' => '338','SampleFormat' => '339','SMinSampleValue' => '340','SMaxSampleValue' => '341','TransferRange' => '342','ClipPath' => '343','XClipPathUnits' => '344','YClipPathUnits' => '345','Indexed' => '346','JPEGTables' => '347','OPIProxy' => '351','GlobalParametersIFD' => '400','ProfileType' => '401','FaxProfile' => '402','CodingMethods' => '403','VersionYear' => '404','ModeNumber' => '405','Decode' => '433','DefaultImageColor' => '434','T82Options' => '435','JPEGTables' => '437','JPEGProc' => '512','ThumbnailOffset' => '513','ThumbnailLength' => '514','JPEGRestartInterval' => '515','JPEGLosslessPredictors' => '517','JPEGPointTransforms' => '518','JPEGQTables' => '519','JPEGDCTables' => '520','JPEGACTables' => '521','YCbCrCoefficients' => '529','YCbCrSubSampling' => '530','YCbCrPositioning' => '531','ReferenceBlackWhite' => '532','StripRowCounts' => '559','ApplicationNotes' => '700','USPTOMiscellaneous' => '999','RelatedImageFileFormat' => '4096','RelatedImageWidth' => '4097','RelatedImageHeight' => '4098','Rating' => '18246','XP_DIP_XML' => '18247','StitchInfo' => '18248','RatingPercent' => '18249','ImageID' => '32781','WangTag1' => '32931','WangAnnotation' => '32932','WangTag3' => '32933','WangTag4' => '32934','Matteing' => '32995','DataType' => '32996','ImageDepth' => '32997','TileDepth' => '32998','Model2' => '33405','CFARepeatPatternDim' => '33421','CFAPattern2' => '33422','BatteryLevel' => '33423','KodakIFD' => '33424','Copyright' => '33432','ExposureTime' => '33434','FNumber' => '33437','MDFileTag' => '33445','MDScalePixel' => '33446','MDColorTable' => '33447','MDLabName' => '33448','MDSampleInfo' => '33449','MDPrepDate' => '33450','MDPrepTime' => '33451','MDFileUnits' => '33452','PixelScale' => '33550','AdventScale' => '33589','AdventRevision' => '33590','UIC1Tag' => '33628','UIC2Tag' => '33629','UIC3Tag' => '33630','UIC4Tag' => '33631','IPTC-NAA' => '33723','IntergraphPacketData' => '33918','IntergraphFlagRegisters' => '33919','IntergraphMatrix' => '33920','INGRReserved' => '33921','ModelTiePoint' => '33922','Site' => '34016','ColorSequence' => '34017','IT8Header' => '34018','RasterPadding' => '34019','BitsPerRunLength' => '34020','BitsPerExtendedRunLength' => '34021','ColorTable' => '34022','ImageColorIndicator' => '34023','BackgroundColorIndicator' => '34024','ImageColorValue' => '34025','BackgroundColorValue' => '34026','PixelIntensityRange' => '34027','TransparencyIndicator' => '34028','ColorCharacterization' => '34029','HCUsage' => '34030','TrapIndicator' => '34031','CMYKEquivalent' => '34032','SEMInfo' => '34118','AFCP_IPTC' => '34152','PixelMagicJBIGOptions' => '34232','ModelTransform' => '34264','WB_GRGBLevels' => '34306','LeafData' => '34310','PhotoshopSettings' => '34377','ExifOffset' => '34665','ICC_Profile' => '34675','TIFF_FXExtensions' => '34687','MultiProfiles' => '34688','SharedData' => '34689','T88Options' => '34690','ImageLayer' => '34732','GeoTiffDirectory' => '34735','GeoTiffDoubleParams' => '34736','GeoTiffAsciiParams' => '34737','ExposureProgram' => '34850','SpectralSensitivity' => '34852','GPSInfo' => '34853','ISO' => '34855','Opto-ElectricConvFactor' => '34856','Interlace' => '34857','TimeZoneOffset' => '34858','SelfTimerMode' => '34859','SensitivityType' => '34864','StandardOutputSensitivity' => '34865','RecommendedExposureIndex' => '34866','ISOSpeed' => '34867','ISOSpeedLatitudeyyy' => '34868','ISOSpeedLatitudezzz' => '34869','FaxRecvParams' => '34908','FaxSubAddress' => '34909','FaxRecvTime' => '34910','LeafSubIFD' => '34954','ExifVersion' => '36864','DateTimeOriginal' => '36867','CreateDate' => '36868','ComponentsConfiguration' => '37121','CompressedBitsPerPixel' => '37122','ShutterSpeedValue' => '37377','ApertureValue' => '37378','BrightnessValue' => '37379','ExposureCompensation' => '37380','MaxApertureValue' => '37381','SubjectDistance' => '37382','MeteringMode' => '37383','LightSource' => '37384','Flash' => '37385','FocalLength' => '37386','FlashEnergy' => '37387','SpatialFrequencyResponse' => '37388','Noise' => '37389','FocalPlaneXResolution' => '37390','FocalPlaneYResolution' => '37391','FocalPlaneResolutionUnit' => '37392','ImageNumber' => '37393','SecurityClassification' => '37394','ImageHistory' => '37395','SubjectArea' => '37396','ExposureIndex' => '37397','TIFF-EPStandardID' => '37398','SensingMethod' => '37399','CIP3DataFile' => '37434','CIP3Sheet' => '37435','CIP3Side' => '37436','StoNits' => '37439','MakerNoteCanon' => '37500','UserComment' => '37510','SubSecTime' => '37520','SubSecTimeOriginal' => '37521','SubSecTimeDigitized' => '37522','MSDocumentText' => '37679','MSPropertySetStorage' => '37680','MSDocumentTextPosition' => '37681','ImageSourceData' => '37724','XPTitle' => '40091','XPComment' => '40092','XPAuthor' => '40093','XPKeywords' => '40094','XPSubject' => '40095','FlashpixVersion' => '40960','ColorSpace' => '40961','ExifImageWidth' => '40962','ExifImageHeight' => '40963','RelatedSoundFile' => '40964','InteropOffset' => '40965','FlashEnergy' => '41483','SpatialFrequencyResponse' => '41484','Noise' => '41485','FocalPlaneXResolution' => '41486','FocalPlaneYResolution' => '41487','FocalPlaneResolutionUnit' => '41488','ImageNumber' => '41489','SecurityClassification' => '41490','ImageHistory' => '41491','SubjectLocation' => '41492','ExposureIndex' => '41493','TIFF-EPStandardID' => '41494','SensingMethod' => '41495','FileSource' => '41728','SceneType' => '41729','CFAPattern' => '41730','CustomRendered' => '41985','ExposureMode' => '41986','WhiteBalance' => '41987','DigitalZoomRatio' => '41988','FocalLengthIn35mmFormat' => '41989','SceneCaptureType' => '41990','GainControl' => '41991','Contrast' => '41992','Saturation' => '41993','Sharpness' => '41994','DeviceSettingDescription' => '41995','SubjectDistanceRange' => '41996','ImageUniqueID' => '42016','OwnerName' => '42032','SerialNumber' => '42033','LensInfo' => '42034','LensMake' => '42035','LensModel' => '42036','LensSerialNumber' => '42037','GDALMetadata' => '42112','GDALNoData' => '42113','Gamma' => '42240','ExpandSoftware' => '44992','ExpandLens' => '44993','ExpandFilm' => '44994','ExpandFilterLens' => '44995','ExpandScanner' => '44996','ExpandFlashLamp' => '44997','PixelFormat' => '48129','Transformation' => '48130','Uncompressed' => '48131','ImageType' => '48132','ImageWidth' => '48256','ImageHeight' => '48257','WidthResolution' => '48258','HeightResolution' => '48259','ImageOffset' => '48320','ImageByteCount' => '48321','AlphaOffset' => '48322','AlphaByteCount' => '48323','ImageDataDiscard' => '48324','AlphaDataDiscard' => '48325','OceScanjobDesc' => '50215','OceApplicationSelector' => '50216','OceIDNumber' => '50217','OceImageLogic' => '50218','Annotations' => '50255','PrintIM' => '50341','USPTOOriginalContentType' => '50560','DNGVersion' => '50706','DNGBackwardVersion' => '50707','UniqueCameraModel' => '50708','LocalizedCameraModel' => '50709','CFAPlaneColor' => '50710','CFALayout' => '50711','LinearizationTable' => '50712','BlackLevelRepeatDim' => '50713','BlackLevel' => '50714','BlackLevelDeltaH' => '50715','BlackLevelDeltaV' => '50716','WhiteLevel' => '50717','DefaultScale' => '50718','DefaultCropOrigin' => '50719','DefaultCropSize' => '50720','ColorMatrix1' => '50721','ColorMatrix2' => '50722','CameraCalibration1' => '50723','CameraCalibration2' => '50724','ReductionMatrix1' => '50725','ReductionMatrix2' => '50726','AnalogBalance' => '50727','AsShotNeutral' => '50728','AsShotWhiteXY' => '50729','BaselineExposure' => '50730','BaselineNoise' => '50731','BaselineSharpness' => '50732','BayerGreenSplit' => '50733','LinearResponseLimit' => '50734','CameraSerialNumber' => '50735','DNGLensInfo' => '50736','ChromaBlurRadius' => '50737','AntiAliasStrength' => '50738','ShadowScale' => '50739','SR2Private' => '50740','MakerNoteSafety' => '50741','RawImageSegmentation' => '50752','CalibrationIlluminant1' => '50778','CalibrationIlluminant2' => '50779','BestQualityScale' => '50780','RawDataUniqueID' => '50781','AliasLayerMetadata' => '50784','OriginalRawFileName' => '50827','OriginalRawFileData' => '50828','ActiveArea' => '50829','MaskedAreas' => '50830','AsShotICCProfile' => '50831','AsShotPreProfileMatrix' => '50832','CurrentICCProfile' => '50833','CurrentPreProfileMatrix' => '50834','ColorimetricReference' => '50879','PanasonicTitle' => '50898','PanasonicTitle2' => '50899','CameraCalibrationSig' => '50931','ProfileCalibrationSig' => '50932','ProfileIFD' => '50933','AsShotProfileName' => '50934','NoiseReductionApplied' => '50935','ProfileName' => '50936','ProfileHueSatMapDims' => '50937','ProfileHueSatMapData1' => '50938','ProfileHueSatMapData2' => '50939','ProfileToneCurve' => '50940','ProfileEmbedPolicy' => '50941','ProfileCopyright' => '50942','ForwardMatrix1' => '50964','ForwardMatrix2' => '50965','PreviewApplicationName' => '50966','PreviewApplicationVersion' => '50967','PreviewSettingsName' => '50968','PreviewSettingsDigest' => '50969','PreviewColorSpace' => '50970','PreviewDateTime' => '50971','RawImageDigest' => '50972','OriginalRawFileDigest' => '50973','SubTileBlockSize' => '50974','RowInterleaveFactor' => '50975','ProfileLookTableDims' => '50981','ProfileLookTableData' => '50982','OpcodeList1' => '51008','OpcodeList2' => '51009','OpcodeList3' => '51022','NoiseProfile' => '51041','Padding' => '59932','OffsetSchema' => '59933','OwnerName' => '65000','SerialNumber' => '65001','Lens' => '65002','KDC_IFD' => '65024','RawFile' => '65100','Converter' => '65101','WhiteBalance' => '65102','Exposure' => '65105','Shadows' => '65106','Brightness' => '65107','Contrast' => '65108','Saturation' => '65109','Sharpness' => '65110','Smoothness' => '65111','MoireFilter' => '65112',);private $tableau_ids_tags_iptc = array('ApplicationRecordVersion' => '0','ObjectTypeReference' => '3','ObjectAttributeReference' => '4','ObjectName' => '5','EditStatus' => '7','EditorialUpdate' => '8','Urgency' => '16','SubjectReference' => '18','Category' => '21','SupplementalCategories' => '32','FixtureIdentifier' => '34','Keywords' => '37','ContentLocationCode' => '38','ContentLocationName' => '39','ReleaseDate' => '48','ReleaseTime' => '53','ExpirationDate' => '55','ExpirationTime' => '56','SpecialInstructions' => '64','ActionAdvised' => '66','ReferenceService' => '69','ReferenceDate' => '71','ReferenceNumber' => '80','DateCreated' => '85','TimeCreated' => '96','DigitalCreationDate' => '98','DigitalCreationTime' => '99','OriginatingProgram' => '101','ProgramVersion' => '112','ObjectCycle' => '117','By-line' => '128','By-lineTitle' => '133','City' => '144','Sub-location' => '146','Province-State' => '149','Country-PrimaryLocationCode' => '256','Country-PrimaryLocationName' => '257','OriginalTransmissionReference' => '259','Headline' => '261','Credit' => '272','Source' => '277','CopyrightNotice' => '278','Contact' => '280','Caption-Abstract' => '288','LocalCaption' => '289','Writer-Editor' => '290','RasterizedCaption' => '293','ImageType' => '304','ImageOrientation' => '305','LanguageIdentifier' => '309','AudioType' => '336','AudioSamplingRate' => '337','AudioSamplingResolution' => '338','AudioDuration' => '339','AudioOutcue' => '340','JobID' => '388','MasterDocumentID' => '389','ShortDocumentID' => '390','UniqueDocumentID' => '391','OwnerID' => '392','ObjectPreviewFileFormat' => '512','ObjectPreviewFileVersion' => '513','ObjectPreviewData' => '514','Prefs' => '545','ClassifyState' => '549','SimilarityIndex' => '552','DocumentNotes' => '560','DocumentHistory' => '561','ExifCameraInfo' => '562','CatalogSets' => '597',);}