запись exif-данных в php

Я пытаюсь создать веб-сайт, где я могу добавлять и изменять метаданные в файле JPEG.

Есть ли способ, которым я могу написать данные exif довольно простым способом.

Я видел один или два примера, но они слишком сложны, чтобы понять в таймфрейме, который мне дали.

Я знаю IPTC, и я знаю, что метаданные могут быть добавлены в файл JPEG. Но каков был бы правильный способ сделать это?

Если кто-то может предоставить некоторую помощь в том, как добавить метаданные в JPEG, используя EXIF ​​или IPTC или любую другую библиотеку или функцию PHP, я был бы очень благодарен.

Обновить:

Прежде всего спасибо за ответ от dbers .

Я просмотрел код. Мне удалось заставить его добавить теги по умолчанию в JPG.

Я все еще немного смущен относительно того, что означают маленькие части кода.

Например, запись exif-данных в php-функцию:

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, PHP Group'

    Я знаю, что вы нашли решение, но это может помочь любому другому, кто ищет то же самое!

    Я изменил класс, который я нашел здесь (спасибо дебютантам ).

    И все ссылки на теги 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) . Библиотека для чтения и записи заголовков Exif в изображениях JPEG и TIFF с использованием PHP.
    • Набор метаданных PHP JPEG . Позволяет читать, записывать и отображать следующие форматы метаданных JPEG: EXIF ​​2.2, XMP / RDF, IPTC-NAA IIM 4.1 ect
    • ExifTool от perl . ExifTool отлично. В основном это все – поддержка EXIF, IPTC и XMP (чтение / запись) и поддержка продлений производителя.

    У меня нет опыта в этом, но на веб-сайте php есть что-то похожее на то, что вы ищете:

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

    Если это то, что вы имели в виду, когда говорили: «Я видел один или два примера, но они слишком сложны, чтобы понять, в какие сроки мне дано».

    Тогда вы можете быть в вашей голове.

    Но примеры на этой странице вообще не кажутся сложными.

    Imagick позволяет вам устанавливать EXIF-данные, но только для объектов в памяти, при записи файла на диск эти данные просто игнорируются. Наиболее популярным решением является либо выход из exiftools, либо использование PHP-библиотеки PEL . Документация PEL разрежена, и API тоже не является самоочевидным.

    Я столкнулся с этой проблемой, пытаясь добавить правильные EXIF-данные к изображениям, которые будут загружены в виде 360 изображений в Facebook, для чего конкретная модель камеры и модель будут указаны как EXIF. В приведенном ниже коде откроется файл изображения, установите его марку и модель и сохраните обратно на диск. Если вы хотите установить другие EXIF-данные, здесь есть полный список всех поддерживаемых PelTag-констант в документах PEL .

     $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'); - $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'); - $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'); - $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'); - $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'); замкнуты $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');