Вопрос

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

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

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

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

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

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

Это было полезно?

Решение

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

<?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;
}

Другие советы

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

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

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


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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top