I\'m trying to create a website where I can add and modify metadata within a JPEG file.
Is there a way in which I can write the exif data in a fairly easy way.
I have no experience with this myself, but php's website has something that looks like what you're looking for:
http://php.net/manual/en/function.iptcembed.php
If thats what you meant when you said "I have seen one or two examples, but they are they too complex to grasp in the timeframe I have been given."
Then you may be in over your head.
But the examples on that page do not look hard to grasp at all.
I know you found the solution, but this might help anyone else that s looking for the same thing!
I modified a class that I found here (thanks debers).
And all the references to IPTC tags can be readed from this PDF
And now the code (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);
?>
Imagick does let you set EXIF-data but only to objects in memory, when writing the file to disk these data is simply ignored. The most popular solution is to either shell out to exiftools or use the PHP-library PEL. The documentation of PEL is sparse, and the API is not really self-explanatory either.
I came across this problem when trying to add the correct EXIF-data to images that would be uploaded as 360 images to Facebook, which requires specific camera make and model to be specified as EXIF. The code below will open an image file, set its make and model, and save back to disk. If you are looking to set other EXIF-data there is a complete list of all supported 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');
Maybe u can try :