2011-03-21 94 views
12

我在创建一个网站,我可以在JPEG文件中添加和修改元数据。在php中写入exif数据

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

我已经看过一两个例子,但它们太复杂,无法在我给出的时间范围内掌握。

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

如果有人能提供有关如何使用PHP的EXIF或IPTC或任何其他库或者功能,那么我会高度赞赏元数据添加到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' => 'Test image', 
'2#116' => 'Copyright 2008-2009, The PHP Group' 

回答

3

我有这个自己没有经验,但PHP的网站上有一些看起来像你找什么:

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

如果那是你说 “我你是什么意思已经看到一两个例子,但它们太复杂了,无法在我给出的时间范围内掌握。“

然后你可能会在你的头上。

但该页面上的示例根本看不出很难理解。

+0

这很简单,而不是写一个长的代码。我想, – 2017-07-24 17:14:21

5

也许ü可以尝试:

  • 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支持(读/写)以及对制造商扩展的支持。
+0

PEL的链接被打破了。尝试 artfulrobot 2017-11-04 19:30:46

12

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

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

并以IPTC标签的所有引用可以从这个PDF

被readed而现在的代码(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); 
?> 
+0

'setValue'工作得很好(用图像编辑器测试过),但'getValue'返回空。任何想法? – azerafati 2017-01-27 10:45:56

0

Imagick不会让你设置的EXIF数据,但只当将文件写入磁盘时,这些数据将被忽略。最流行的解决方案是将shell或exiftools使用PHP库PEL。 PEL的文档很少,API也不是很明确。

当我试图将正确的EXIF数据添加到将作为360图像上传到Facebook的图像时,我遇到了这个问题,这需要将特定的相机品牌和型号指定为EXIF。下面的代码将打开一个图像文件,设置其制造商和型号,并保存回磁盘。如果您正在设置其他EXIF数据,则会提供所有支持的PelTag常量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');