сделать данные IPTC доступными для поиска - PullRequest
0 голосов
/ 13 сентября 2009

У меня есть вопрос о метаданных IPTC. Можно ли искать изображения, которых нет в базе данных, по их метаданным (ключевым словам) IPTC и показывать их, и как мне поступить? Мне просто нужна основная идея.

Я знаю, что есть функция iptcparse () для PHP.

Я уже написал функцию для захвата имени изображения, местоположения и расширения для всех изображений в папке галереи и всех подкаталогах с расширением .jpg.

Мне нужно выяснить, как извлечь метаданные, не сохраняя их в базе данных, и как осуществлять поиск по ним, получить соответствующие изображения, соответствующие поисковому тегу (их ключевые слова IPTC должны совпадать), и как их отображать. В тот момент, когда у меня есть окончательные результаты (пост-поиск), я могу отобразить тег изображения с src = "$ filelocation">, если у меня есть окончательные результаты в массиве.

По сути, я не уверен, нужно ли мне сохранять все мои изображения в базе данных mysql, а также извлекать ключевые слова и сохранять их в базе данных, прежде чем я смогу выполнить поиск и отобразить результаты. Кроме того, если бы вы могли вести меня в любую галерею, которая уже может это сделать, это также могло бы помочь.

Спасибо за любую помощь по этому вопросу.

Ответы [ 2 ]

3 голосов
/ 13 сентября 2009

Непонятно, что именно вызывает у вас проблемы, но, возможно, это даст вам несколько идей:

<?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 голосов
/ 13 сентября 2009

Если вы не извлекли эти данные IPTC из ваших изображений, каждый раз, когда кто-то будет искать, вам придется:

  • петля на каждом изображении
  • для каждого изображения извлеките данные IPTC
  • посмотреть, соответствуют ли данные IPTC для текущего изображения

Если у вас есть больше, чем пара изображений, это будет очень плохо для выступлений, я бы сказал.


Так что, на мой взгляд, было бы гораздо лучше:

  • добавить пару полей в вашу базу данных
  • извлечение соответствующих данных IPTC при загрузке / сохранении изображения
  • сохранить данные IPTC в этих полях БД
  • поиск в этих полях БД
    • Или используйте какой-нибудь поисковик, например, Lucene или Sphinx, но это другая проблема.

Это будет означать немного больше работы для вас прямо сейчас: у вас есть больше кода для записи ...

... Но это также означает, что у вашего веб-сайта будет больше шансов выжить, когда есть несколько изображений и многие пользователи выполняют поиск.

...