2011-03-21 101 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');