2009-09-13 3 views
0

J'ai une question sur les métadonnées IPTC. Est-il possible de rechercher des images qui ne sont pas dans une base de données par leurs métadonnées IPTC (mots-clés) et de les montrer et comment vais-je faire cela? J'ai juste besoin d'une idée de base.rendre les données IPTC consultables

Je sais qu'il y a la fonction iptcparse() pour PHP.

J'ai déjà écrit une fonction pour saisir le nom de l'image, l'emplacement et l'extension pour toutes les images dans un dossier galeries et tous les sous-répertoires par extension .jpg. Je dois trouver comment extraire les métadonnées sans les stocker dans une base de données et comment les parcourir, saisir les images correspondantes à la balise de recherche (leurs mots-clés IPTC devraient correspondre) et comment les afficher. Je sais au point que j'ai les résultats finaux (post-recherche) je peux faire écho un imagetag avec src = "$ filelocation"> si j'ai les résultats finaux dans un tableau. Fondamentalement, je ne suis pas sûr si j'ai besoin de stocker toutes mes images dans une base de données MySQL et aussi d'extraire les mots-clés et de les stocker dans la base de données avant de pouvoir réellement rechercher et afficher les résultats. Aussi, si vous pouviez me guider vers une galerie qui est déjà capable de faire cela, cela pourrait aussi aider.

Merci pour toute aide concernant ce problème.

Répondre

3

On ne sait pas ce qui est en particulier de vous donner des problèmes, mais peut-être cela vous donnera quelques idées:

<?php 
# Images we're searching 
$images = array('/path/to/image.jpg', 'another-image.jpg'); 

# IPTC keywords to values (from exiv2, see below) 
$query = array('Byline' => 'Some Author'); 

# Perform the search 
$result = select_jpgs_by_iptc_fields($images, $query); 

# Display the results 
foreach ($result as $path) { 
    echo '<img src="', htmlspecialchars($path), '">'; 
} 

function select_jpgs_by_iptc_fields($jpgs, $query) { 
    $matches = array(); 
    foreach ($jpgs as $path) { 
     $iptc = get_jpg_iptc_metadata($path); 
     foreach ($query as $name => $values) { 
      if (!is_array($values)) 
       $values = array($values); 
      if (count(array_intersect($iptc[$name], $values)) != count($values)) 
       continue 2; 
     } 
     $matches[] = $path; 
    } 
    return $matches; 
} 

function get_jpg_iptc_metadata($path) { 
    $size = getimagesize($path, $info); 
    if(isset($info['APP13'])) 
    { 
     return human_readable_iptc(iptcparse($info['APP13'])); 
    } 
    else { 
     return null; 
    } 
} 

function human_readable_iptc($iptc) { 
# From the exiv2 sources 
static $iptc_codes_to_names = 
array( 
// IPTC.Envelope--> 
"1#000" => 'ModelVersion', 
"1#005" => 'Destination', 
"1#020" => 'FileFormat', 
"1#022" => 'FileVersion', 
"1#030" => 'ServiceId', 
"1#040" => 'EnvelopeNumber', 
"1#050" => 'ProductId', 
"1#060" => 'EnvelopePriority', 
"1#070" => 'DateSent', 
"1#080" => 'TimeSent', 
"1#090" => 'CharacterSet', 
"1#100" => 'UNO', 
"1#120" => 'ARMId', 
"1#122" => 'ARMVersion', 
// <-- IPTC.Envelope 
// IPTC.Application2 --> 
"2#000" => 'RecordVersion', 
"2#003" => 'ObjectType', 
"2#004" => 'ObjectAttribute', 
"2#005" => 'ObjectName', 
"2#007" => 'EditStatus', 
"2#008" => 'EditorialUpdate', 
"2#010" => 'Urgency', 
"2#012" => 'Subject', 
"2#015" => 'Category', 
"2#020" => 'SuppCategory', 
"2#022" => 'FixtureId', 
"2#025" => 'Keywords', 
"2#026" => 'LocationCode', 
"2#027" => 'LocationName', 
"2#030" => 'ReleaseDate', 
"2#035" => 'ReleaseTime', 
"2#037" => 'ExpirationDate', 
"2#038" => 'ExpirationTime', 
"2#040" => 'SpecialInstructions', 
"2#042" => 'ActionAdvised', 
"2#045" => 'ReferenceService', 
"2#047" => 'ReferenceDate', 
"2#050" => 'ReferenceNumber', 
"2#055" => 'DateCreated', 
"2#060" => 'TimeCreated', 
"2#062" => 'DigitizationDate', 
"2#063" => 'DigitizationTime', 
"2#065" => 'Program', 
"2#070" => 'ProgramVersion', 
"2#075" => 'ObjectCycle', 
"2#080" => 'Byline', 
"2#085" => 'BylineTitle', 
"2#090" => 'City', 
"2#092" => 'SubLocation', 
"2#095" => 'ProvinceState', 
"2#100" => 'CountryCode', 
"2#101" => 'CountryName', 
"2#103" => 'TransmissionReference', 
"2#105" => 'Headline', 
"2#110" => 'Credit', 
"2#115" => 'Source', 
"2#116" => 'Copyright', 
"2#118" => 'Contact', 
"2#120" => 'Caption', 
"2#122" => 'Writer', 
"2#125" => 'RasterizedCaption', 
"2#130" => 'ImageType', 
"2#131" => 'ImageOrientation', 
"2#135" => 'Language', 
"2#150" => 'AudioType', 
"2#151" => 'AudioRate', 
"2#152" => 'AudioResolution', 
"2#153" => 'AudioDuration', 
"2#154" => 'AudioOutcue', 
"2#200" => 'PreviewFormat', 
"2#201" => 'PreviewVersion', 
"2#202" => 'Preview', 
// <--IPTC.Application2 
    ); 
    $human_readable = array(); 
    foreach ($iptc as $code => $field_value) { 
     $human_readable[$iptc_codes_to_names[$code]] = $field_value; 
    } 
    return $human_readable; 
} 
+0

Vous écrasez les premières entrées dans la 'iptc_codes_to_names' $ avec ceux plus tard avec le même nombre. Pourquoi n'utilisez-vous pas la chaîne comme index pour ce tableau? – fragmentedreality

+0

Vous avez raison. Je l'ai copié à partir du code source exiv2 c et j'ai probablement fait une erreur en effectuant la conversion de c en code php. J'utilise ints parce que ... j'ai probablement pensé qu'un code est supposé être numérique. C'est à peu près la même chose si j'utilise des chaînes de chiffres en tant que clés. (Les zéros en tête dans les codes entrants comme #ne fonctionneraient pas avec les clés de chaîne, mais ce n'est pas la raison pour laquelle j'utilise ints, sinon je l'aurais commenté). – Inshallah

+0

Toujours votre code entraîne '$ iptc_codes_to_names [0] == 'RecordVersion'' (la valeur ' ModelVersion 'est remplacée). Les champs IPTC.Envelope qui ont le même numéro que les champs IPTC.Application2 sont perdus. J'ai déjà suggéré une modification apportant ce changement, mais je n'ai pas encore été accepté. Pour moi les index fonctionnent sous cette forme: '$ iptc_codes_to_names ['1 # 000'] = 'ModelVersion'; $ iptc_codes_to_names ['2 # 000'] = 'RecordVersion''. – fragmentedreality

0

Si vous n'avez extrait les données IPTC de vos images, chaque fois que quelqu'un va chercher, vous devrez:

    boucle
  • sur toutes les images
  • pour chaque image, extraire le IPTC données
  • voir si les données IPTC de l'image actuelle correspond

Si vous avez plus d'une image couple, ce sera vraiment mauvais pour les performances, je dirais.


Donc, à mon avis, il serait beaucoup mieux:

  • ajouter deux champs dans votre base de données
  • extraire les données IPTC pertinentes lorsque l'image est téléchargée/stockée
  • stocker les données IPTC dans les champs DB
  • recherche dans les champs DB
    • Ou u Il y a un moteur de recherche comme Lucene ou Sphinx - mais c'est un autre problème.

Ça va vouloir dire un peu plus de travail pour vous en ce moment: vous avez plus de code à écrire ...

... Mais cela signifie aussi votre site aura de meilleures chances de survivre quand il y a plusieurs images et que beaucoup d'utilisateurs font des recherches.

Questions connexes