【问题标题】:writing exif data in php用php编写exif数据
【发布时间】:2018-04-27 13:33:20
【问题描述】:

我正在尝试创建一个网站,我可以在其中添加和修改 JPEG 文件中的元数据。

有没有一种方法可以让我以相当简单的方式编写 exif 数据。

我见过一两个例子,但它们太复杂了,在我给定的时间范围内无法掌握。

我知道 IPTC 并且我知道可以将元数据添加到 JPEG 文件中。但是这样做的正确方法是什么?

如果有人可以就如何使用 EXIF 或 IPTC 或 PHP 的任何其他库或功能将元数据添加到 JPEG 提供一些帮助,我将不胜感激。

更新:

首先感谢dbers的回复。

我查看了代码。我已经设法让它将默认标签添加到 JPG 中。

对于代码的一小部分的含义,我仍然有些困惑。

例如在php函数中写入exif数据:

function iptc_make_tag($rec, $data, $value) 
{ 
    $length = strlen($value); 
    $retval = chr(0x1C) . chr($rec) . chr($data);
    ...
}

我还没有遇到函数变量,如果尚未定义 $rec$data$value,它们是如何被引用的。还是取自iptc_make_tag

我回显了$rec$value,但我没有在屏幕上返回值。

if(isset($info['APP13']))

我不确定 APP13 是什么意思,当我尝试回显 $info 时,当我在表格中回显 $info 时,我只会得到以下信息。

'2#120' => '测试图像', '2#116' => '版权所有 2008-2009,PHP 集团'

【问题讨论】:

    标签: php metadata jpeg exif


    【解决方案1】:

    我知道你找到了解决方案,但这可能会帮助其他正在寻找相同东西的人!

    我修改了一个类,发现here(感谢debers)。

    所有对IPTC标签的引用都可以从这个PDF中读取

    现在是代码(PHP >= 5.4):

    <?
    define("IPTC_OBJECT_NAME", "005");
    define("IPTC_EDIT_STATUS", "007");
    define("IPTC_PRIORITY", "010");
    define("IPTC_CATEGORY", "015");
    define("IPTC_SUPPLEMENTAL_CATEGORY", "020");
    define("IPTC_FIXTURE_IDENTIFIER", "022");
    define("IPTC_KEYWORDS", "025");
    define("IPTC_RELEASE_DATE", "030");
    define("IPTC_RELEASE_TIME", "035");
    define("IPTC_SPECIAL_INSTRUCTIONS", "040");
    define("IPTC_REFERENCE_SERVICE", "045");
    define("IPTC_REFERENCE_DATE", "047");
    define("IPTC_REFERENCE_NUMBER", "050");
    define("IPTC_CREATED_DATE", "055");
    define("IPTC_CREATED_TIME", "060");
    define("IPTC_ORIGINATING_PROGRAM", "065");
    define("IPTC_PROGRAM_VERSION", "070");
    define("IPTC_OBJECT_CYCLE", "075");
    define("IPTC_BYLINE", "080");
    define("IPTC_BYLINE_TITLE", "085");
    define("IPTC_CITY", "090");
    define("IPTC_PROVINCE_STATE", "095");
    define("IPTC_COUNTRY_CODE", "100");
    define("IPTC_COUNTRY", "101");
    define("IPTC_ORIGINAL_TRANSMISSION_REFERENCE", "103");
    define("IPTC_HEADLINE", "105");
    define("IPTC_CREDIT", "110");
    define("IPTC_SOURCE", "115");
    define("IPTC_COPYRIGHT_STRING", "116");
    define("IPTC_CAPTION", "120");
    define("IPTC_LOCAL_CAPTION", "121");
    
    class IPTC
    {
        var $meta = [];
        var $file = null;
    
        function __construct($filename)
        {
            $info = null;
    
            $size = getimagesize($filename, $info);
    
            if(isset($info["APP13"])) $this->meta = iptcparse($info["APP13"]);
    
            $this->file = $filename;
        }
    
        function getValue($tag)
        {
            return isset($this->meta["2#$tag"]) ? $this->meta["2#$tag"][0] : "";
        }
    
        function setValue($tag, $data)
        {
            $this->meta["2#$tag"] = [$data];
    
            $this->write();
        }
    
        private function write()
        {
            $mode = 0;
    
            $content = iptcembed($this->binary(), $this->file, $mode);   
    
            $filename = $this->file;
    
            if(file_exists($this->file)) unlink($this->file);
    
            $fp = fopen($this->file, "w");
            fwrite($fp, $content);
            fclose($fp);
        }         
    
        private function binary()
        {
            $data = "";
    
            foreach(array_keys($this->meta) as $key)
            {
                $tag = str_replace("2#", "", $key);
                $data .= $this->iptc_maketag(2, $tag, $this->meta[$key][0]);
            }       
    
            return $data;
        }
    
        function iptc_maketag($rec, $data, $value)
        {
            $length = strlen($value);
            $retval = chr(0x1C) . chr($rec) . chr($data);
    
            if($length < 0x8000)
            {
                $retval .= chr($length >> 8) .  chr($length & 0xFF);
            }
            else
            {
                $retval .= chr(0x80) . 
                           chr(0x04) . 
                           chr(($length >> 24) & 0xFF) . 
                           chr(($length >> 16) & 0xFF) . 
                           chr(($length >> 8) & 0xFF) . 
                           chr($length & 0xFF);
            }
    
            return $retval . $value;            
        }   
    
        function dump()
        {
            echo "<pre>";
            print_r($this->meta);
            echo "</pre>";
        }
    
        #requires GD library installed
        function removeAllTags()
        {
            $this->meta = [];
            $img = imagecreatefromstring(implode(file($this->file)));
            if(file_exists($this->file)) unlink($this->file);
            imagejpeg($img, $this->file, 100);
        }
    }
    
    $file = "photo.jpg";
    $objIPTC = new IPTC($file);
    
    //set title
    $objIPTC->setValue(IPTC_HEADLINE, "A title for this picture");
    
    //set description
    $objIPTC->setValue(IPTC_CAPTION, "Some words describing what can be seen in this picture.");
    
    echo $objIPTC->getValue(IPTC_HEADLINE);
    ?>
    

    【讨论】:

    • setValue 工作正常(使用图像编辑器测试)但getValue 返回空。有什么想法吗?
    【解决方案2】:

    也许你可以试试:

    • PEL(PHP Exif Library)。一个使用 PHP 读取和写入 JPEG 和 TIFF 图像中的 Exif 标头的库。
    • The PHP JPEG Metadata Toolkit。允许读取、写入和显示以下 JPEG 元数据格式:EXIF 2.2、XMP / RDF、IPTC-NAA IIM 4.1 等
    • ExifTool by perl。 ExifTool 非常棒。它基本上应有尽有 - EXIF、IPTC 和 XMP 支持(读/写)以及对制造商扩展的支持。

    【讨论】:

    • 我认为 PEL 的链接已损坏。试试 packagist.org/packages/lsolesen/pel>
    【解决方案3】:

    Imagick 确实允许您设置 EXIF 数据,但仅限于内存中的对象,当将文件写入磁盘时,这些数据会被简单地忽略。最流行的解决方案是使用 exiftools 或使用 PHP 库 PEL。 PEL 的文档很少,API 也不是很清楚。

    我在尝试将正确的 EXIF 数据添加到将作为 360 度图像上传到 Facebook 的图像时遇到了这个问题,这需要将特定的相机品牌和型号指定为 EXIF。下面的代码将打开一个图像文件,设置其品牌和型号,然后保存回磁盘。如果您正在寻找设置其他 EXIF 数据,这里有所有受支持的 PelTag-constants here in the PEL docs 的完整列表。

    $data = new PelDataWindow(file_get_contents('IMAGE PATH'));
    $tiff = null;
    $file = null;
    
    // If it is a JPEG-image, check if EXIF-headers exists
    if (PelJpeg::isValid($data)) {
        $jpeg = $file = new PelJpeg();
        $jpeg->load($data);
        $exif = $jpeg->getExif();
    
        // If no EXIF in image, create it
        if($exif == null) {
            $exif = new PelExif();
            $jpeg->setExif($exif);
    
            $tiff = new PelTiff();
            $exif->setTiff($tiff);
        }
        else {
            $tiff = $exif->getTiff();
        }
    }
    // If it is a TIFF EXIF-headers will always be set
    elseif (PelTiff::isValid($data)) {
        $tiff = $file = new PelTiff();
        $tiff->load($data);
    }
    else {
        throw new \Exception('Invalid image format');
    }
    
    // Get the first Ifd, where most common EXIF-tags reside
    $ifd0 = $tiff->getIfd();
    
    // If no Ifd info found, create it
    if($ifd0 == null) {
        $ifd0 = new PelIfd(PelIfd::IFD0);
        $tiff->setIfd($ifd0);
    }
    
    // See if the MAKE-tag already exists in Ifd
    $make = $ifd0->getEntry(PelTag::MAKE);
    
    // Create MAKE-tag if not found, otherwise just change the value
    if($make == null) {
        $make = new PelEntryAscii(PelTag::MAKE, 'RICOH');
        $ifd0->addEntry($make);
    }
    else {
        $make->setValue('RICOH');
    }
    
    // See if the MODEL-tag already exists in Ifd
    $model = $ifd0->getEntry(PelTag::MODEL);
    
    // Create MODEL-tag if not found, otherwise just change the value
    if($model == null) {
        $model = new PelEntryAscii(PelTag::MODEL, 'RICOH THETA S');
        $ifd0->addEntry($model);
    }
    else {
        $model->setValue('RICOH THETA S');
    }
    
    // Save to disk
    $file->saveFile('IMAGE.jpg');
    

    【讨论】:

    • PEL 文档链接已损坏,这是一个有效的链接 -> github.com/pel/pel/blob/master/src/PelTag.php
    • @Andreas Bergström 我来到了一个库miljar/php-exif,它允许您读取和设置 exif 数据。然而,我的问题是如何将更新的属性保存到原始文件或新文件中。
    • 我对这个库有很多问题
    【解决方案4】:

    我自己没有这方面的经验,但是 php 的网站有一些看起来像你正在寻找的东西:

    http://php.net/manual/en/function.iptcembed.php

    如果这就是你所说的意思 “我见过一两个例子,但它们太复杂了,在我给定的时间范围内无法掌握。”

    那么你可能会不知所措。

    但是该页面上的示例看起来一点也不难掌握。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-30
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      相关资源
      最近更新 更多