FEP-ee3a: Exif metadata support

Hi everyone!

This discussion concerns a FEP that describes how platforms can add support for exchanging Exif metadata between each other. This metadata can be extracted from image and audio files and is typically added automatically by the devices that create those files (for example digital cameras).

Photographers very often share Exif data today, usually by including it manually in the status content (often as an emoji followed by a value). However, this process is entirely manual. Client applications, on the other hand, are able to read this metadata automatically and after explicit user confirmation (which is a critical step) store it in their databases and exchange it with other platforms.

For photography-oriented platforms, this enables additional functionality, such as filtering photos taken with a specific camera body, a particular lens, and similar criteria.

PR: #750 - FEP-ee3a: Exif metadata support - fediverse/fep - Codeberg.org

4 Likes

Nice work, Pixelfed is interested in supporting this as we’re now going to display EXIF data (opt-in) and want to federate it.

Link to the FEP text: FEP-ee3a: Exif metadata support

1 Like

I also like the idea! I did a first draft for the WordPress plugin: Add EXIF metadata support for image attachments by pfefferle · Pull Request #2751 · Automattic/wordpress-activitypub · GitHub

I’m also wondering whether the FEP should explicitly state that platforms must strip all EXIF metadata from files before storing them and distributing them to other instances. It seems like everyone knows this and already does it, but it may be worth documenting explicitly.

it looks like https://w3id.org/fep/ee3a uses http://schema.org/PropertyValue but there is already a long-existing vocabulary for EXIF data in http://www.w3.org/2003/12/exif/

using it with jsonld instead of rdf/xml, it might look like this:

{
  "@id": "_:b9",
  "@type": "http://www.w3.org/2003/12/exif/ns/IFD",
  "http://www.w3.org/2003/12/exif/ns/dateTime": "2003-01-18T16:07:30",
  "http://www.w3.org/2003/12/exif/ns/exif_IFD_Pointer": {
    "@id": "_:b10",
    "@type": "http://www.w3.org/2003/12/exif/ns/IFD",
    "http://www.w3.org/2003/12/exif/ns/apertureValue": "116/32",
    "http://www.w3.org/2003/12/exif/ns/colorSpace": "sRGB",
    "http://www.w3.org/2003/12/exif/ns/componentsConfiguration": "01 02 03 00",
    "http://www.w3.org/2003/12/exif/ns/compressedBitsPerPixel": "5/1",
    "http://www.w3.org/2003/12/exif/ns/dateTimeDigitized": "2003-01-18T16:07:30",
    "http://www.w3.org/2003/12/exif/ns/dateTimeOriginal": "2003-01-18T16:07:30",
    "http://www.w3.org/2003/12/exif/ns/exifVersion": "2.20",
    "http://www.w3.org/2003/12/exif/ns/exposureBiasValue": "96",
    "http://www.w3.org/2003/12/exif/ns/exposureTime": "1/400",
    "http://www.w3.org/2003/12/exif/ns/fNumber": "35/10",
    "http://www.w3.org/2003/12/exif/ns/flash": "Flash fired, compulsory flash mode, red-eye reduction mode",
    "http://www.w3.org/2003/12/exif/ns/flashpixVersion": "1.00",
    "http://www.w3.org/2003/12/exif/ns/focalLength": "294/32",
    "http://www.w3.org/2003/12/exif/ns/maxApertureValue": "116/32",
    "http://www.w3.org/2003/12/exif/ns/meteringMode": "Pattern",
    "http://www.w3.org/2003/12/exif/ns/shutterSpeedValue": "76"
  },
  "http://www.w3.org/2003/12/exif/ns/make": "Canon",
  "http://www.w3.org/2003/12/exif/ns/model": "Canon IXY DIGITAL 30",
  "http://www.w3.org/2003/12/exif/ns/orientation": "top-left",
  "http://www.w3.org/2003/12/exif/ns/resolutionUnit": "inch",
  "http://www.w3.org/2003/12/exif/ns/xResolution": "180/1",
  "http://www.w3.org/2003/12/exif/ns/yCbCrPositioning": "centered",
  "http://www.w3.org/2003/12/exif/ns/yResolution": "180/1"
}

compacted with a prefix, it might look like this:

{
  "@context": {
    "exif": "http://www.w3.org/2003/12/exif/ns/"
  },
  "@id": "_:b9",
  "@type": "exif:IFD",
  "exif:dateTime": "2003-01-18T16:07:30",
  "exif:exif_IFD_Pointer": {
    "@id": "_:b10",
    "@type": "exif:IFD",
    "exif:apertureValue": "116/32",
    "exif:colorSpace": "sRGB",
    "exif:componentsConfiguration": "01 02 03 00",
    "exif:compressedBitsPerPixel": "5/1",
    "exif:dateTimeDigitized": "2003-01-18T16:07:30",
    "exif:dateTimeOriginal": "2003-01-18T16:07:30",
    "exif:exifVersion": "2.20",
    "exif:exposureBiasValue": "96",
    "exif:exposureTime": "1/400",
    "exif:fNumber": "35/10",
    "exif:flash": "Flash fired, compulsory flash mode, red-eye reduction mode",
    "exif:flashpixVersion": "1.00",
    "exif:focalLength": "294/32",
    "exif:maxApertureValue": "116/32",
    "exif:meteringMode": "Pattern",
    "exif:shutterSpeedValue": "76"
  },
  "exif:make": "Canon",
  "exif:model": "Canon IXY DIGITAL 30",
  "exif:orientation": "top-left",
  "exif:resolutionUnit": "inch",
  "exif:xResolution": "180/1",
  "exif:yCbCrPositioning": "centered",
  "exif:yResolution": "180/1"
}

you could proceed to come up with some context using term definitions and your desired mapping to “plain JSON” output. at minimum, you compact the following graph:

{
  "http://www.w3.org/2003/12/exif/ns/exifdata": {
    "@type": "http://www.w3.org/2003/12/exif/ns/IFD",
  "http://www.w3.org/2003/12/exif/ns/make": "Canon",
  "http://www.w3.org/2003/12/exif/ns/model": "Canon IXY DIGITAL 30",
  "http://www.w3.org/2003/12/exif/ns/dateTime": "2003-01-18T16:07:30",
  "http://www.w3.org/2003/12/exif/ns/exif_IFD_Pointer": {
    "http://www.w3.org/2003/12/exif/ns/apertureValue": "116/32",
    "http://www.w3.org/2003/12/exif/ns/colorSpace": "sRGB",
    "http://www.w3.org/2003/12/exif/ns/exposureTime": "1/400",
    "http://www.w3.org/2003/12/exif/ns/fNumber": "35/10",
    "http://www.w3.org/2003/12/exif/ns/flash": "Flash fired, compulsory flash mode, red-eye reduction mode",
    "http://www.w3.org/2003/12/exif/ns/focalLength": "294/32"
  }
  }
}

against the following context:

{
  "exif": "http://www.w3.org/2003/12/exif/ns/",
  "exifdata": {
    "@id": "exif:exifdata",
    "@context": {
      "@vocab": "http://www.w3.org/2003/12/exif/ns/"
    }
  }
}

and get the following “plain JSON” serialization:

{
  "@context": {
    "exif": "http://www.w3.org/2003/12/exif/ns/",
    "exifdata": {
      "@id": "exif:exifdata",
      "@context": {
        "@vocab": "http://www.w3.org/2003/12/exif/ns/"
      }
    }
  },
  "exifdata": {
    "@type": "IFD",
    "dateTime": "2003-01-18T16:07:30",
    "exif_IFD_Pointer": {
      "apertureValue": "116/32",
      "colorSpace": "sRGB",
      "exposureTime": "1/400",
      "fNumber": "35/10",
      "flash": "Flash fired, compulsory flash mode, red-eye reduction mode",
      "focalLength": "294/32"
    },
    "make": "Canon",
    "model": "Canon IXY DIGITAL 30"
  }
}

i’m not 100% sure if that’s “correct” since i haven’t looked at the namespace for that long, but i wanted to point you to existing prior work at least.

1 Like