views:

969

answers:

3

PHP has built in support for reading EXIF and IPTC metadata, but I can't find any way to read XMP?

+5  A: 

XMP data is literally embedded into the image file so can extract it with PHP's string-functions from the image file itself.

The following demonstrates this procedure (I'm using SimpleXML but every other XML API or even simple and clever string parsing may give you equal results):

$content = file_get_contents($image);
$xmp_data_start = strpos($content, '<x:xmpmeta');
$xmp_data_end   = strpos($content, '</x:xmpmeta>');
$xmp_length     = $xmp_data_end - $xmp_data_start;
$xmp_data       = substr($content, $xmp_data_start, $xmp_length + 12);
$xmp            = simplexml_load_string($xmp_data);

Just two remarks:

  • XMP makes heavy use of XML namespaces, so you'll have to keep an eye on that when parsing the XMP data with some XML tools.
  • considering the possible size of image files, you'll perhaps not be able to use file_get_contents() as this function loads the whole image into memory. Using fopen() to open a file stream resource and checking chunks of data for the key-sequences <x:xmpmeta and </x:xmpmeta> will significantly reduce the memory footprint.
Stefan Gehrig
That would explain why there is no XMP specific functions in PHP.
Liam
A: 

I'm only replying to this after so much time because this seems to be the best result when searching Google for how to parse XMP data. I've seen this nearly identical snippet used in code a few times and it's a terrible waste of memory. Here is an example of the fopen() method Stefan mentions after his example, reading 1024 bytes at a time (of course, you could make the chunk size a parameter, just be sure to validate it!):

function getXmpData($filename)
{
   $chunk_size = 1024;
   $buffer = NULL;

   if (($file_pointer = fopen($filename, 'r')) === FALSE)
   {
      throw new RuntimeException('Could not open file for reading');
   }

   $found_start = FALSE;

   while (($chunk = fread($file_pointer, $chunk_size)) !== FALSE) 
   {
      if (($pos = strpos($chunk, '<x:xmpmeta')) !== FALSE)
      {
         $found_start = TRUE;
         $buffer .= substr($chunk, $pos); 
      }
      elseif (($pos = strpos($chunk, '</x:xmpmeta>')) !== FALSE)
      {
         $buffer .= substr($chunk, 0, $pos + 12);
         break; 
      }
      elseif ($found_start)
      {
         $buffer .= $chunk;
      }
      // end elseif // ($found_start) //
   }
   // end while // (($chunk = fread($file_pointer, $chunk_size) !== FALSE) //

   fclose($file_pointer);

   return $buffer;
}
Bryan Geraghty
A: 

Hi, I've developped the Xmp Php Tookit extension : it's a php5 extension based on the adobe xmp toolkit, which provide the main classes and method to read/write/parse xmp metadatas from jpeg, psd, pdf, video, audio... This extension is under gpl licence. A new release will be available soon, for php 5.3 (now only compatible with php 5.2.x), and should be available on windows and macosx (now only for freebsd and linux systems). http://xmpphptoolkit.sourceforge.net/

Mathias Vitalis