繁体   English   中英

在php中写入exif数据

[英]writing exif data in php

我正在尝试创建一个网站,我可以在其中添加和修改 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 ,我只会得到以下$info

'2#120' => 'Test image',
'2#116' => 'Copyright 2008-2009, The PHP Group'

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

我修改了我在这里找到的一个类(感谢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);
?>

也许你可以尝试:

  • PEL(PHP Exif 库) 使用 PHP 在 JPEG 和 TIFF 图像中读取和写入 Exif 标头的库。
  • PHP JPEG 元数据工具包 允许读取、写入和显示以下 JPEG 元数据格式:EXIF 2.2、XMP / RDF、IPTC-NAA IIM 4.1 等
  • Perl 的 ExifTool ExifTool 非常棒。 它基本上已经具备了 - EXIF、IPTC 和 XMP 支持(读/写)以及对制造商扩展的支持。

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

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

$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');

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

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

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

那么你可能会不知所措。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM