Запись exif-данных в php
Я пытаюсь создать сайт, на котором я могу добавлять и изменять метаданные в файле JPEG.
Есть ли способ, которым я могу писать данные exif довольно простым способом.
Я видел один или два примера, но они слишком сложны, чтобы понять в таймфрейме, который мне дал.
Я знаю IPTC, и я знаю, что метаданные могут быть добавлены в файл JPEG. Но каков был бы правильный способ сделать это?
Если кто-то может оказать некоторую помощь в том, как добавить метаданные в JPEG, используя EXIF или IPTC или любую другую библиотеку или функцию PHP, я был бы очень благодарен.
Update:
Прежде всего спасибо за ответ 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
в таблице.
'2#120' => 'Test image',
'2#116' => 'Copyright 2008-2009, The PHP Group'
Ответы
Ответ 1
Я знаю, что вы нашли решение, но это может помочь любому другому, кто ищет то же самое!
Я изменил класс, который нашел здесь (спасибо debers).
И все ссылки на теги 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);
?>
Ответ 2
Возможно, вы можете попробовать:
- 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 (чтение/запись) и поддержка продлений производителя.
Ответ 3
У меня нет опыта с этим, но на веб-сайте php есть что-то похожее на то, что вы ищете:
http://php.net/manual/en/function.iptcembed.php
Если это то, что вы имели в виду, когда говорили
"Я видел один или два примера, но они слишком сложны, чтобы понять сроки, которые мне даны".
Тогда вы можете быть в вашей голове.
Но примеры на этой странице вообще не кажутся сложными.
Ответ 4
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');