2011-03-21 47 views
12

Estoy intentando crear un sitio web donde pueda agregar y modificar metadatos dentro de un archivo JPEG.escribiendo datos exif en php

Hay una manera en que puedo escribir los datos exif de una manera bastante fácil.

He visto uno o dos ejemplos, pero son demasiado complejos como para captarlos en el marco de tiempo que me han dado.

Conozco IPTC y sé que los metadatos se pueden agregar al archivo JPEG. Pero, ¿cuál sería la forma correcta de hacer esto?

Si alguien pudiera ayudarme a agregar metadatos a JPEG utilizando EXIF ​​o IPTC o cualquier otra biblioteca o característica de PHP, le agradecería enormemente.

Actualización:

Ante todo gracias por la respuesta por dbers.

He revisado el código. Me las he arreglado para agregar las etiquetas predeterminadas al JPG.

Todavía estoy un poco confundido en cuanto a lo que significan pequeñas porciones del código.

Por ejemplo escribir los datos EXIF ​​en la función de php:

function iptc_make_tag($rec, $data, $value) 
{ 
    $length = strlen($value); 
    $retval = chr(0x1C) . chr($rec) . chr($data); 
    ... 
} 

No he venido a través de una variable de función, y cómo se está haciendo referencia $rec, $data y $value si has sido definidas. ¿O están tomadas desde el iptc_make_tag?

Hice eco de $rec y $value pero no obtengo un valor en la pantalla.

if(isset($info['APP13'])) 

no estoy seguro de lo que significa APP13 y cuando intento hacer eco a cabo $info, acabo de conseguir lo siguiente cuando me echo a cabo $info en una tabla.

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

Respuesta

3

no tengo experiencia con este mismo, pero el sitio web de PHP tiene algo que se parece a lo que estás buscando:

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

Si eso es lo que quería decir cuando dijo "Yo He visto uno o dos ejemplos, pero son demasiado complejos como para captarlos en el marco de tiempo que me han dado ".

Entonces puede estar por encima de su cabeza.

Pero los ejemplos en esa página no parecen difíciles de entender en absoluto.

+0

Es simple en lugar de escribir un código largo. El enlace –

5

Quizás u puede probar:

  • PEL(PHP Exif Library). Una biblioteca para leer y escribir encabezados Exif en imágenes JPEG y TIFF usando PHP.
  • The PHP JPEG Metadata Toolkit. Permite leer, escribir y visualizar los siguientes formatos de metadatos JPEG: EXIF ​​2.2, XMP/RDF, IPTC-NAA IIM 4.1 ecto
  • ExifTool by perl. El ExifTool es excelente. Básicamente lo tiene todo: soporte EXIF, IPTC y XMP (lectura/escritura) y soporte para extensiones de fabricante.
+0

a PEL está roto, creo. Pruebe artfulrobot

12

Sé que ha encontrado la solución, ¡pero esto podría ayudar a cualquier otra persona que esté buscando lo mismo!

Modifiqué una clase que encontré here (gracias debers).

Y todas las referencias a las etiquetas IPTC pueden ser leidos de esta PDF

Y ahora el código (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); 
?> 
+0

'setValue' funciona correctamente (probado con un editor de imágenes) pero' getValue' devuelve vacío. ¿alguna idea? – azerafati

0

Imagick Qué le permiten establecer datos EXIF ​​pero sólo a objetos en la memoria, al escribir el archivo en el disco estos datos simplemente se ignoran. La solución más popular es pagar por exiftools o usar la biblioteca PHP PEL. La documentación de PEL es escasa, y la API tampoco se explica por sí misma.

Me encontré con este problema al intentar agregar los datos EXIF ​​correctos a las imágenes que se cargarían como imágenes de 360 ​​en Facebook, lo que requiere que la marca y el modelo específicos de la cámara se especifiquen como EXIF. El siguiente código abrirá un archivo de imagen, establecerá su marca y modelo, y lo guardará nuevamente en el disco. Si está buscando establecer otros datos EXIF, hay una lista completa de todas las constantes de PelTag compatibles 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'); 
Cuestiones relacionadas