While I myself have not used this, the XMP PHP Toolkit on sourceforge sounds like what you can look for: http://xmpphptoolkit.sourceforge.net/ That said - it is in alpha and has not been updated for a year, it appears.
The XMP Toolkit PHP Extension is a PHP module that includes the Adobe XMP Toolkit SDK. This PHP5 extension will provide classes and methods for manipulating XMP metadata from files such as jpegs, tiff, png, but also wav, mp3, avi, mpeg4, pdf, ai, eps ... Based on Adobe XMP SDK Toolkit 4.4.2. The purpose of this extension is to have php classes that can open files, extract metadata, manipulate them and put them back in a few lines of php code. This project is under the GPL v3 License.
You can also write arbitrary metadata to the image file using iptcembed. As you noted in your comment, this only works for JPEG files.
http://php.net/manual/en/function.iptcembed.php
Here is the script from the comments of the class that will receive and set the IPTC data:
<? 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=Array(); var $hasmeta=false; var $file=false; function iptc($filename) { $size = getimagesize($filename,$info); $this->hasmeta = isset($info["APP13"]); if($this->hasmeta) $this->meta = iptcparse ($info["APP13"]); $this->file = $filename; } function set($tag, $data) { $this->meta ["2#$tag"]= Array( $data ); $this->hasmeta=true; } function get($tag) { return isset($this->meta["2#$tag"]) ? $this->meta["2#$tag"][0] : false; } function dump() { print_r($this->meta); } function binary() { $iptc_new = ''; foreach (array_keys($this->meta) as $s) { $tag = str_replace("2#", "", $s); $iptc_new .= $this->iptc_maketag(2, $tag, $this->meta[$s][0]); } return $iptc_new; } function iptc_maketag($rec,$dat,$val) { $len = strlen($val); if ($len < 0x8000) { return chr(0x1c).chr($rec).chr($dat). chr($len >> 8). chr($len & 0xff). $val; } else { return chr(0x1c).chr($rec).chr($dat). chr(0x80).chr(0x04). chr(($len >> 24) & 0xff). chr(($len >> 16) & 0xff). chr(($len >> 8 ) & 0xff). chr(($len ) & 0xff). $val; } } function write() { if(!function_exists('iptcembed')) return false; $mode = 0; $content = iptcembed($this->binary(), $this->file, $mode); $filename = $this->file; @unlink($filename);
Example copyright line:
$i = new iptc("test.jpg"); echo $i->get(IPTC_COPYRIGHT_STRING);
Update copyright statement:
$i = new iptc("test.jpg"); echo $i->set(IPTC_COPYRIGHT_STRING,"Here goes the new data"); $i->write();