Writing XMP Metadata in jpeg (with PHP) - Using Single or Multiple rdf:Description blocks

mseifert

I am attempting to modify the code from PHP_JPEG_Metadata_Toolkit so that I can read and write XMP data correctly for jpeg files using PHP. Currently, the jpeg files (when saved by the Toolkit) give errors with Adobe Photoshop & Bridge because of the XMP block.

There are two ways I'm seeing the XMP RDF schema used by Photoshop. The first is what Photoshop is actually saving in the jpg and which I am importing. Photoshop uses a single rdf:Description block for everything. It throws many schema identifiers (urls) within the block itself PLUS adds values for many metadata fields. Then following are tag blocks for Dublin Core, Photoshop, Iptc4xmpCore, etc., but all lumped together within a single Description tag.

The second is the neatly formatted Metadata displayed inside of Photoshop "File Info" that follows the XMP documentation for RDF (which states "By convention, all properties from a given schema, and only that schema, are listed within a single rdf:Description element.")

I've been able to fix the problem with Photoshop giving errors when edited by the Toolkit by following the example of what Photoshop actually sends (everything under one rdf:Description)

Two questions: Any idea why Photoshop saving the XMP metadata different from what it shows inside the program? And … Why should I spend the time to format my output to the RDF specs when it works nicely all jumbled together in a single rdf:Description? I am new to working with all this and so any guidance would be appreciated.

These examples are edited so you can more easily see the formatting differences only - please forgive content discrepancies between the two that are just from editing.

Here is what I am actually receiving from Photoshop (edited):

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
  <rdf:Description rdf:about="" 
        xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" 
        xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" 
        xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" 
        xmlns:xmp="http://ns.adobe.com/xap/1.0/" 
        xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/" 
        xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/" 
        xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" 
        xmlns:dc="http://purl.org/dc/elements/1.1/"             
        xmpMM:DocumentID="xmp.did:8808E8B6139411E3A70AB29CEEC8FF6C"
        xmpMM:InstanceID="xmp.iid:0071BBEF4517E311BCBCC2DF868D188C"
        xmpMM:OriginalDocumentID="" 
        xmp:CreatorTool="(PHP JPEG Metadata Toolkit v1.12)" 
        xmp:MetadataDate="2013-09-06T15:44:49-07:00" 
        xmp:ModifyDate="2013-09-06T15:44:49-07:00" 
        xmp:CreateDate="2013-09-06T15:22:46-07:00" 
        xmpRights:Marked="True" 
        xmpRights:WebStatement="MY WEB ADDRESS" 
        Iptc4xmpCore:IntellectualGenre="" 
        photoshop:Instructions="OOOInstructions" 
        photoshop:Headline="OOOHeadline" 
        photoshop:CaptionWriter="MY NAME" 
        dc:format="image/jpeg"> 
        <xmpMM:DerivedFrom stRef:instanceID="6B5F4850BB0819F254E40401F67ACAC9" 
        <stRef:documentID="6B5F4850BB0819F254E40401F67ACAC9"/> 

    <xmpRights:UsageTerms> 
        <rdf:Alt> 
            <rdf:li xml:lang="x-default">MY INFO HERE</rdf:li> 
        </rdf:Alt> 
    </xmpRights:UsageTerms> 

    <dc:description> 
        <rdf:Alt> 
        <rdf:li xml:lang="x-default">OOODescription
        </rdf:li> 
        </rdf:Alt> 
    </dc:description> 

  </rdf:Description> 
</rdf:RDF> 

Here is Photoshops nicely formatted view (edited)

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <rdf:Description rdf:about=""
        xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
        xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
        xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#">
     <xmpMM:DocumentID>xmp.did: … ETC…</xmpMM:DocumentID>
     <xmpMM:InstanceID>xmp.iid: …ETC… </xmpMM:InstanceID>
     <xmpMM:OriginalDocumentID/>
     <xmpMM:DerivedFrom rdf:parseType="Resource">
        <stRef:instanceID>6B5F4850BB0819F254E40401F67ACAC9</stRef:instanceID>
        <stRef:documentID>6B5F4850BB0819F254E40401F67ACAC9</stRef:documentID>
     </xmpMM:DerivedFrom>
  </rdf:Description>

  <rdf:Description rdf:about=""
        xmlns:xmp="http://ns.adobe.com/xap/1.0/">
     <xmp:CreatorTool>Adobe Photoshop CS6 (Windows)</xmp:CreatorTool>
     <xmp:MetadataDate>2013-09-06T15:44:49-07:00</xmp:MetadataDate>
     <xmp:ModifyDate>2013-09-06T15:44:49-07:00</xmp:ModifyDate>
     <xmp:CreateDate>2013-09-06T15:22:46-07:00</xmp:CreateDate>
  </rdf:Description>

  <rdf:Description rdf:about=""
        xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/">
     <xmpRights:Marked>True</xmpRights:Marked>
     <xmpRights:WebStatement>MY WEB ADDRESS</xmpRights:WebStatement>
     <xmpRights:UsageTerms>
        <rdf:Alt>
           <rdf:li xml:lang="x-default">MY INFO HERE</rdf:li>
        </rdf:Alt>
     </xmpRights:UsageTerms>
  </rdf:Description>

  <rdf:Description rdf:about=""
        xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/">
     <Iptc4xmpCore:IntellectualGenre/>
  </rdf:Description>

  <rdf:Description rdf:about=""
        xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
     <photoshop:Instructions>OOOInstructions</photoshop:Instructions>
     <photoshop:Headline>OOOHeadline</photoshop:Headline>
     <photoshop:CaptionWriter>OOO </photoshop:CaptionWriter>
  </rdf:Description>

  <rdf:Description rdf:about=""
        xmlns:dc="http://purl.org/dc/elements/1.1/">
     <dc:format>image/jpeg</dc:format>
     <dc:description>
        <rdf:Alt>
           <rdf:li xml:lang="x-default">OOODescription</rdf:li>
        </rdf:Alt>
     </dc:description>
  </rdf:Description>
</rdf:RDF>

Edit I appreciate Joshua's explanation. What I find interesting/odd is that there appears to be two different ways to list a value. The first is with an equal sign as in tag="value" and included within the rdf:Description brackets (notice closing rdf:Description bracket):

<rdf:Description rdf:about="" 
   xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmpRights:Marked="True" 
   photoshop:Instructions="Notice closing Bracket here">
</rdf:Description> 

The second is with Value

<rdf:Description rdf:about=""
   xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
   <photoshop:Instructions>OOOInstructions</photoshop:Instructions>
</rdf:Description> 
Joshua Taylor

About RDF

It appears that what Photoshop is doing is reading a valid, well formed, RDF/XML serialization of some data, and then displaying it back to the user in UI in another valid, well-formed, RDF/XML serialization that happens to follow some additional conventions.

RDF is a graph-based data representation. The fundamental piece of knowledge in RDF is the triple, also called a statement. Each triple has a subject, a predicate, and an object. Subjects, predicates, and objects may all be IRI references; subjects and objects can also be blank nodes, and objects may also be literals (e.g., a string). RDF/XML is one particular serialization of RDF. The RDF/XML snippet:

<rdf:Description rdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
  <photoshop:Instructions>OOOInstructions</photoshop:Instructions>
  <photoshop:Headline>OOOHeadline</photoshop:Headline>
  <photoshop:CaptionWriter>OOO </photoshop:CaptionWriter>
</rdf:Description>

contains three triples:

<this-document> <http://ns.adobe.com/photoshop/1.0/Instructions> "OOOInstructions"
<this-document> <http://ns.adobe.com/photoshop/1.0/Headline> "OOOHeadline"
<this-document> <http://ns.adobe.com/photoshop/1.0/CaptionWriter> "OOO "

where <this-document> is the result of resolving the reference "" (the value of the rdf:about attribute. (Page 21 of the XMP documentation says that the value of the rdf:about attribute may be an empty string …, which means that the XMP is physically local to the resource being described. Applications must rely on knowledge of the file format to correctly associate the XMP with the resource".)

Doing

<rdf:Description rdf:about=""
    xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/">
  <Iptc4xmpCore:IntellectualGenre/>
</rdf:Description>

<rdf:Description rdf:about=""
    xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
  <photoshop:Instructions>OOOInstructions</photoshop:Instructions>
  <photoshop:Headline>OOOHeadline</photoshop:Headline>
  <photoshop:CaptionWriter>OOO </photoshop:CaptionWriter>
</rdf:Description>

is exactly the same as doing

<rdf:Description rdf:about=""
    xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
    xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
  <Iptc4xmpCore:IntellectualGenre/>
  <photoshop:Instructions>OOOInstructions</photoshop:Instructions>
  <photoshop:Headline>OOOHeadline</photoshop:Headline>
  <photoshop:CaptionWriter>OOO </photoshop:CaptionWriter>
</rdf:Description>

They serialize the same set of triples. Neither is invalid or incorrect. It's just a matter of which you prefer. Other variations are possible as well. For instance, in some cases you can use element attributes to indicate property values. The triple:

<this-document> <http://ns.adobe.com/photoshop/1.0/Instructions> "OOOInstructions"

can be seralized using elements, as described in Section 2.2 Node Elements and Property Elements of the RDF/XML recommendation:

<rdf:Description rdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
  <photoshop:Instructions>OOOInstructions</photoshop:Instructions>
</rdf:Description> 

or using attributes to indicate the property value, as described in Section 2.5 Property Attributes of the same document:

<rdf:Description rdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
    photoshop:Instructions="OOOInstructions">
</rdf:Description>

So, as to your second question:

Why should I spend the time to format my output to the RDF specs when it works nicely all jumbled together in a single rdf:Description?

If the output is supposed to be in RDF, you should make it valid RDF. Whether it's in a particular aesthetically pleasing format is an entirely different question. It's relatively easy to translate between the two of these, and I expect that what Photoshop is doing is reading a blob of RDF as it should (i.e., not depending on any particular structure of the XML serialization, since that's not always the same (e.g., you shouldn't try to manipulate RDF with XPath)) and then formatting that data for the user in a way that it considers nice, namely, the convention that you mentioned.

If you're not already, I very strongly suggest that you use an RDF library in PHP to construct the metadata graph, and not try to construct the RDF/XML serialization by hand.

About XMP in RDF

Note: this is an update based on the documentation. According to the documentation, page 19, XMP only supports a subset of RDF, so it is still a meaningful question about whether the RDF above and in the question, though suitable as RDF, is suitable as XMP. However, also from page 19:

The sections below describe the high-level structure of XMP data in an XMP Packet:

  • The outermost element is optionally an x:xmpmeta element
  • It contains a single rdf:RDF element
  • which in turn contains one or more rdf:Description elements
  • each of which contains one or more XMP Properties.

Page 20 contains some elaboration about the rdf:Description elements (emphasis added):

The rdf:RDF element can contain one or more rdf:Description elements. … By convention, all properties from a given schema, and only that schema, are listed within a single rdf:Description element. (This is not a requirement, just a means to improve readability.)

The part with added emphasis is what we need in order to conclude that both forms we've seen above are acceptable. It's probably easier to just create one big blob, and consider yourself lucky if some other tool splits it into the conventional form for you.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Writing multiple post requests using single connection - PHP

From Dev

how to convert multiple div into image (png/jpeg) using php and javascript?

From Dev

Is XMP metadata supported in PNG images?

From Dev

Multiple if blocks or single if/else block?

From Dev

Extjs 4, How to send multiple metaData for multiple dynamic grids, using a single Json file

From Dev

How do I add XMP metadata to each page of an existing PDF using iTextSharp

From Dev

RDF document metadata

From Dev

Writing text blocks using nested iteration in Vim

From Dev

Receiving multiple variables from ajax & writing it to text file using php

From Dev

Receiving multiple variables from ajax & writing it to text file using php

From Dev

iText -> Best approach to read XMP metadata?

From Dev

Updating RDF data using php on sesame server

From Dev

JPEG and PNG metadata compression

From Dev

Configure IntelliJ to comment single line PHP blocks

From Dev

PHP Formatter for single-line code blocks

From Dev

Multiple data blocks in a single file and a single plot + Markers for each block

From Dev

Syntax of animating in gnuplot using 'blocks' in a single file

From Dev

A license catalog with RDF description, exist?

From Dev

writing an excel formula with multiple options for a single parameter

From Dev

writing single query from multiple query

From Dev

writing single query from multiple query

From Dev

Outputting to a file, not using headers for a jpeg using a PHP

From Dev

Writing query for multiple tables in php

From Dev

Using a for loop to save multiple ggplot as jpeg

From Dev

Replace multiple commas in a string with a single comma using php

From Dev

Multiple values in single input field using php.

From Dev

how to insert multiple checkbox values in single column in database using php

From Dev

How to merge Multiple arrays into single array using PHP

From Dev

PHP Strange Whitespace is created while writing files. (blocks CSS)

Related Related

  1. 1

    Writing multiple post requests using single connection - PHP

  2. 2

    how to convert multiple div into image (png/jpeg) using php and javascript?

  3. 3

    Is XMP metadata supported in PNG images?

  4. 4

    Multiple if blocks or single if/else block?

  5. 5

    Extjs 4, How to send multiple metaData for multiple dynamic grids, using a single Json file

  6. 6

    How do I add XMP metadata to each page of an existing PDF using iTextSharp

  7. 7

    RDF document metadata

  8. 8

    Writing text blocks using nested iteration in Vim

  9. 9

    Receiving multiple variables from ajax & writing it to text file using php

  10. 10

    Receiving multiple variables from ajax & writing it to text file using php

  11. 11

    iText -> Best approach to read XMP metadata?

  12. 12

    Updating RDF data using php on sesame server

  13. 13

    JPEG and PNG metadata compression

  14. 14

    Configure IntelliJ to comment single line PHP blocks

  15. 15

    PHP Formatter for single-line code blocks

  16. 16

    Multiple data blocks in a single file and a single plot + Markers for each block

  17. 17

    Syntax of animating in gnuplot using 'blocks' in a single file

  18. 18

    A license catalog with RDF description, exist?

  19. 19

    writing an excel formula with multiple options for a single parameter

  20. 20

    writing single query from multiple query

  21. 21

    writing single query from multiple query

  22. 22

    Outputting to a file, not using headers for a jpeg using a PHP

  23. 23

    Writing query for multiple tables in php

  24. 24

    Using a for loop to save multiple ggplot as jpeg

  25. 25

    Replace multiple commas in a string with a single comma using php

  26. 26

    Multiple values in single input field using php.

  27. 27

    how to insert multiple checkbox values in single column in database using php

  28. 28

    How to merge Multiple arrays into single array using PHP

  29. 29

    PHP Strange Whitespace is created while writing files. (blocks CSS)

HotTag

Archive