XMP FAQ

How do I adjust the automatic guessing of missing XMP tags?

The auto_xmp active binding for xmp() objects is a character vector of XMP tags that if missing {xmpdf} will try to automatically guess based on values of other XMP tags and the spdx_id active binding (SPDX License List Identifer). When printing xmp() objects one can observe which XMP tags are guessed because they’ll have a => on their left.

library("xmpdf")
x <- xmp(creator = "John Doe", date_created = "2023-02-10", spdx_id = "CC-BY-4.0")
print(x)
## i  spdx_id (not XMP tag) := CC-BY-4.0
## i  auto_xmp (not XMP tag) := cc:attributionName, cc:license, dc:rights, dc:subject,
##         photoshop:Credit, xmpRights:Marked, xmpRights:UsageTerms,
##         xmpRights:WebStatement
## => cc:attributionName = John Doe
## => cc:license = https://creativecommons.org/licenses/by/4.0/
##    dc:creator := John Doe
## => dc:rights = © 2023 John Doe. Some rights reserved.
## => photoshop:Credit = John Doe
##    photoshop:DateCreated := 2023-02-10
## => xmpRights:Marked = TRUE
## => xmpRights:UsageTerms = This work is licensed to the public under the Creative Commons
##         Attribution 4.0 International license
##         https://creativecommons.org/licenses/by/4.0/
## => xmpRights:WebStatement = https://creativecommons.org/licenses/by/4.0/

If you remove an XMP tag from auto_xmp then {xmpdf} will no longer try to guess it:

library("xmpdf")
x <- xmp(creator = "John Doe", date_created = "2023-02-10", spdx_id = "CC-BY-4.0")
x$auto_xmp <- base::setdiff(x$auto_xmp,
                            c("dc:rights", "photoshop:Credit"))
print(x)
## i  spdx_id (not XMP tag) := CC-BY-4.0
## i  auto_xmp (not XMP tag) := cc:attributionName, cc:license, dc:subject, xmpRights:Marked,
##         xmpRights:UsageTerms, xmpRights:WebStatement
## => cc:attributionName = John Doe
## => cc:license = https://creativecommons.org/licenses/by/4.0/
##    dc:creator := John Doe
##    photoshop:DateCreated := 2023-02-10
## => xmpRights:Marked = TRUE
## => xmpRights:UsageTerms = This work is licensed to the public under the Creative Commons
##         Attribution 4.0 International license
##         https://creativecommons.org/licenses/by/4.0/
## => xmpRights:WebStatement = https://creativecommons.org/licenses/by/4.0/

Alternatively you could explicitly set a missing XMP tag (which then would no longer need to be guessed):

library("xmpdf")
x <- xmp(creator = "John Doe", date_created = "2023-02-10")
x$rights <- "© 2023 A Corporation. Some rights reserved."
print(x)
## i  auto_xmp (not XMP tag) := cc:attributionName, cc:license, dc:rights, dc:subject,
##         photoshop:Credit, xmpRights:Marked, xmpRights:UsageTerms,
##         xmpRights:WebStatement
## => cc:attributionName = John Doe
##    dc:creator := John Doe
##    dc:rights := © 2023 A Corporation. Some rights reserved.
## => photoshop:Credit = John Doe
##    photoshop:DateCreated := 2023-02-10

Which XMP tags have an active binding?

XMP tags with an active binding in xmp() objects will automatically be coerced into the right data type and are a little easier to get/set than XMP tags without an active binding. Here is a list of current active bindings provided by xmp() objects:

Active Binding XMP tag
alt_text Iptc4xmpCore:AltTextAccessibility
attribution_name cc:attributionName
attribution_url cc:attributionURL
create_date xmp:CreateDate
creator dc:creator
creator_tool xmp:CreatorTool
credit photoshop:Credit
date_created photoshop:DateCreated
description dc:description
ext_description Iptc4xmpCore:ExtDescrAccessibility
headline photoshop:Headline
keywords pdf:Keywords
license cc:license
marked xmpRights:Marked
modify_date xmp:ModifyDate
more_permissions cc:morePermissions
producer pdf:Producer
rights dc:rights
subject dc:subject
title dc:title
usage_terms xmpRights:UsageTerms
web_statement xmpRights:WebStatement

How do I get or set XMP tags without an active binding?

If you want to set an XMP tag without an active binding you must use the xmp() objects set_item() method. To get an XMP without an active binding you must use the xmp() objects get_item() method. You may also use get_item() and set_item() for XMP tags with an active binding as well.

library("xmpdf")
x <- xmp()
x$set_item("dc:contributor", c("John Doe", "Jane Doe"))
x$get_item("dc:contributor")
## [1] "John Doe" "Jane Doe"

Depending on the value type of the XMP tag you may need to manually coerce it to a special R class:

XMP value type R function to coerce
date datetimeoffset::as_datetimeoffset()
lang-alt xmpdf::as_lang_alt()
library("datetimeoffset")
library("xmpdf")
transcript <- c(en = "An English Transcript", 
                fr = "Une transcription française") |>
                  as_lang_alt(default_lang = "en")
last_edited <- "2020-02-04T10:10:10" |>
                   as_datetimeoffset()
x <- xmp()
x$set_item("Iptc4xmpExt:Transcript", transcript)
x$set_item("Iptc4xmpExt:IPTCLastEdited", last_edited)

What XMP tags are used to display informaton on Google Images?

Google Images can show more details about an image when certain metadata is specified:

  1. Structured data on the web page the image appears (takes priority over XMP tags if defined)

  2. XMP tags embedded in the image

    • dc:creator
    • photoshop:Credit
    • dc:rights
    • xmpRights:WebStatement
    • the Licensor URL subfield of plus:Licensor structured XMP tag

xmp() object’s print(mode = "google_images") will tell what the Google Images XMP tags metadata would be:

library("xmpdf")
x <- xmp(attribution_url = "https://example.com/attribution",
         creator = "John Doe",
         description = "An image caption",
         date_created = Sys.Date(),
         spdx_id = "CC-BY-4.0")
print(x, mode = "google_images", xmp_only = TRUE)
##    dc:creator := John Doe
## => dc:rights = © 2024 John Doe. Some rights reserved.
## => photoshop:Credit = John Doe
## X  plus:Licensor (not currently supported by {xmpdf})
## => xmpRights:WebStatement = https://creativecommons.org/licenses/by/4.0/

Which tags should I use for Creative Commons license information?

Creative Commons recommends you specify the following XMP tags to indicate your license information:

  • dc:rights
  • xmpRight:Marked
  • xmpRights:WebStatement
  • xmpRights:UsageTerms
  • cc:license
  • cc:morePermissions
  • cc:attributionURL
  • cc:attributionName

xmp() object’s print(mode = "creative_commons") will tell what this XMP tags metadata would be:

library("xmpdf")
x <- xmp(attribution_url = "https://example.com/attribution",
         creator = "John Doe",
         description = "An image caption",
         date_created = Sys.Date(),
         spdx_id = "CC-BY-4.0")
print(x, mode = "creative_commons", xmp_only = TRUE)
## => cc:attributionName = John Doe
##    cc:attributionURL := https://example.com/attribution
## => cc:license = https://creativecommons.org/licenses/by/4.0/
##    cc:morePermissions := NULL
## => dc:rights = © 2024 John Doe. Some rights reserved.
## => xmpRights:Marked = TRUE
## => xmpRights:UsageTerms = This work is licensed to the public under the Creative Commons
##         Attribution 4.0 International license
##         https://creativecommons.org/licenses/by/4.0/
## => xmpRights:WebStatement = https://creativecommons.org/licenses/by/4.0/

How do I embed XMP metadata in multiple languages?

Although some XMP metadata tags must be a string in a single language but some XMP metadata tags support “language alternative aka”lang-alt” values which allow values for multiple languages to be specified:

  • Iptc4xmpCore:AltTextAccessibility
  • dc:description
  • Iptc4xmpCore:ExtDescrAccessibility
  • dc:rights
  • dc:title
  • xmpRights:UsageTerms
  • Plus other XMP tags which will need to be manually coerced by as_lang_alt() and set with the xmp() object’s set_item() method

See ?as_lang_alt for more details but essentially create a character vector or list and name the entries with an RFC 3066 name tag.

library("xmpdf")
x <- xmp()
x$description <- "Description in only one default language"
x$title <- c(en = "An English Title",
             fr = "Une titre française")
# XMP tags without an active binding must be manually coerced by `as_lang_alt`
transcript <- c(en = "An English Transcript",
                fr = "Une transcription française") |>
                  as_lang_alt(default_lang = "en")
x$set_item("Iptc4xmpExt:Transcript", transcript)

How do I enter in a “structured” tag?

Currently {xmpdf} does not officially support entering in “struct” XMP tags (although it does support “lang-alt” tags and simple lists of basic XMP value types).

If necessary you’ll need to use an external program such as exiftool (perhaps via {exiftoolr}) to embed structured XMP tags.

Is there an easy way to embed XMP metadata when using {knitr}?

{knitr} supports the chunk option fig.process which accepts a function to post-process figure files. The first argument should be a path to the figure file and may optionally accept an options argument which will receive a list of chunk options. It should return a (possibly new) path to be inserted in the output.

xmp() objects have a fig_process() method which return a function that can be used for this fig.process option to embed XMP metadat into images. Depending on the strings in its auto argument this function will also automatically map the following {knitr} chunk options to XMP tags:

  • fig.cap to dc:description
  • fig.scap to photoshop:Headline
  • fig.alt to Iptc4xmpCore:AltTextAccessibility
.. {r setup, echo=FALSE}
x <- xmpdf::xmp(creator = "John Doe", 
                date_created = "2023", 
                spdx_id = "CC-BY-4.0",
                attribution_url = "https://example.com/attribution")
knitr::opts_chunk$set(fig.process = x$fig_process())
.. ..