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

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

13 голосов
/ 22 марта 2011

Я пытаюсь создать веб-сайт, на котором я могу добавлять и изменять метаданные в файле 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 в таблице.

'2#120' => 'Test image',
'2#116' => 'Copyright 2008-2009, The PHP Group'

Ответы [ 4 ]

14 голосов
/ 27 июля 2013

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

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

И все ссылки на теги IPTC можно прочитать из этого PDF

А теперь код (PHP> = 5.4):

<code><?
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 "
"; } #requires установлена ​​библиотека GD функция 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 = новый IPTC ($ file); // установить заголовок $ objIPTC-> setValue (IPTC_HEADLINE, «Заголовок для этого изображения»); // установить описание $ objIPTC-> setValue (IPTC_CAPTION, "Некоторые слова, описывающие то, что можно увидеть на этом рисунке."); echo $ objIPTC-> getValue (IPTC_HEADLINE); ?>
5 голосов
/ 31 декабря 2011

Может быть, вы можете попробовать:

  • PEL (PHP Exif Library) . Библиотека для чтения и записи заголовков Exif в изображениях JPEG и TIFF с использованием PHP.
  • Набор метаданных PHP JPEG . Позволяет читать, записывать и отображать следующие форматы метаданных JPEG: EXIF ​​2.2, XMP / RDF, IPTC-NAA IIM 4.1 и т. Д.
  • ExifTool от perl . ExifTool отлично. В основном все это есть - поддержка EXIF, IPTC и XMP (чтение / запись) и поддержка расширений производителя.
3 голосов
/ 22 марта 2011

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

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

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

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

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

2 голосов
/ 12 сентября 2017

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

Я столкнулся с этой проблемой при попытке добавить правильные EXIF-данные к изображениям, которые будут загружены в Facebook как 360 изображений, для чего необходимо указать конкретную марку камеры и модель в качестве 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');
...