读取图像的IPTC数据

8

我在读取一些图片的IPTC数据时遇到了一些问题,我之所以想这样做,是因为我的客户已经将所有关键字都存储在IPTC数据中,不想在网站上重新输入它们。

所以我创建了这个简单的脚本来读取它们:

$size = getimagesize($image, $info);

if(isset($info['APP13'])) {
    $iptc = iptcparse($info['APP13']);

    print '<pre>';
        var_dump($iptc['2#025']);
    print '</pre>';
}

这通常情况下可以完美运行,但是对于一些图片来说会有问题。

注意:未定义索引:2#025

虽然我在Photoshop中可以清晰地看到关键词。

是否有任何良好的小型库可以读取每个图像中的关键词?或者我在这里做错了什么?


我注意到这只发生在用Photoshop CS3保存的图像上。 - woutr_be
3个回答

1

我见过很多奇怪的IPTC问题。可能是你有2个APP13段。我注意到,由于某些原因,一些JPEG具有多个IPTC块。这可能是使用几个照片编辑程序或某些手动文件操作的问题。

可能是PHP试图读取空的APP13甚至嵌入式“缩略图元数据”的问题。

也可能是段长度的问题 - APP13或8BIM具有长度标记字节,可能具有错误的值。

尝试使用HEX编辑器并手动检查文件。


1
我发现IPTC几乎总是使用XMP格式嵌入为xml,而且通常不在APP13槽中。有时候可以通过使用iptcparse($info['APP1'])来获取IPTC信息,但最可靠的方法是从相关的xml字符串中搜索图像文件,以便获得它(我从另一个答案中得到了这个方法,但我找不到它,否则我会提供链接!)。
关键词的xml始终采用以下形式:"<dc:subject>...<rdf:Seq><rdf:li>Keyword 1</rdf:li><rdf:li>Keyword 2</rdf:li>...<rdf:li>Keyword N</rdf:li></rdf:Seq>...</dc:subject>" 因此,您只需将文件作为字符串使用file_get_contents(get_attached_file($attachment_id))获取,使用strpos()查找每个打开(<rdf:li>)和关闭(</rdf:li>)XML标记,并使用substr()抓取它们之间的关键词即可。
以下代码片段适用于我测试过的所有jpeg格式的图片。它将从ID为$attachment_id的WordPress图片中获取IPTC标签,并将其填充到数组$keys中。
$content = file_get_contents(get_attached_file($attachment_id));

// Look for xmp data: xml tag "dc:subject" is where keywords are stored
$xmp_data_start = strpos($content, '<dc:subject>') + 12;

// Only proceed if able to find dc:subject tag
if ($xmp_data_start != FALSE) {
    $xmp_data_end   = strpos($content, '</dc:subject>');
    $xmp_data_length     = $xmp_data_end - $xmp_data_start;
    $xmp_data       = substr($content, $xmp_data_start, $xmp_data_length);

    // Look for tag "rdf:Seq" where individual keywords are listed
    $key_data_start = strpos($xmp_data, '<rdf:Seq>') + 9;

    // Only proceed if able to find rdf:Seq tag
    if ($key_data_start != FALSE) {
        $key_data_end   = strpos($xmp_data, '</rdf:Seq>');
        $key_data_length     = $key_data_end - $key_data_start;
        $key_data       = substr($xmp_data, $key_data_start, $key_data_length);

        // $ctr will track position of each <rdf:li> tag, starting with first
        $ctr = strpos($key_data, '<rdf:li>');

        // Initialize empty array to store keywords
        $keys = Array();

        // While loop stores each keyword and searches for next xml keyword tag
        while($ctr != FALSE && $ctr < $key_data_length) {
            // Skip past the tag to get the keyword itself
            $key_begin = $ctr + 8;

            // Keyword ends where closing tag begins
            $key_end = strpos($key_data, '</rdf:li>', $key_begin);

            // Make sure keyword has a closing tag
            if ($key_end == FALSE) break;

            // Make sure keyword is not too long (not sure what WP can handle)
            $key_length = $key_end - $key_begin;
            $key_length = (100 < $key_length ? 100 : $key_length);

            // Add keyword to keyword array
            array_push($keys, substr($key_data, $key_begin, $key_length));

            // Find next keyword open tag
            $ctr = strpos($key_data, '<rdf:li>', $key_end);
        }
    }
} 

我已经在一个插件中实现了这个功能,将IPTC关键词放入WP的“描述”字段中,您可以在此处找到

0

ExifTool非常强大,如果你可以从PHP中调用它的话(看起来是这样?)


谢谢,但不幸的是我不能在当前托管上运行shell命令。 - woutr_be

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接