Handling Image metadata

From RidgeRun Developer Wiki






Introduction

The metadata, also called "data about data", stores additional information from the primary content that is already when the image is taken. This information could be the condition in which the image was taken, for example: shutter speed, exposure, gain, white balance, and lens information [1]. In order to provide some guidance, the Guidelines for handling image metadata documentation could be consulted.

The metadata in an image can be managed by different actors according to their roles. These actors use their definitions to access and manage the image metadata. The definitions start with a Creator going through Changer actors and ending with the Consumer actor. This workflow can be seen in the following diagram:


Actor state diagram. Taken from Guidelines for handling image metadata


In general, the actors mentioned above perform the following actions[1]:

  • Creator: Creates the first metadata instances in a new image file. It is common that there is no old metadata to preserve.
  • Changer: It first reads the metadata and then modifies it back to the image or writes new metadata.
  • Consumer: This actor does not modify the metadata in the file itself, only reads and exposes it for display purposes, research, etc.

This wiki page is focused on JPEG image format.

Types of metadata

According to Guidelines for handling image metadata there are three types of standard metadata that are used in the images the most: EXIF, IPTC and XMP.

EXIF

EXIF stands for Exchangeable Image File Format and this standard stores the additional metadata in digital images [2]. The EXIF format borrows some set TIFF tags in order to describe the photographic images [1].

In the JPEG Compressed Image Format, the EXIF Attribute Information is written in the Application Market Segment (APP1) and the APP1 size shall not exceed the 64 KBytes specified in the PEG standard. Other APPn that APP1 and APP2 or COM (Comment) segments are not used by EXIF. However, they are not restricted, they can be used for recording by vendors or trade groups. The APP1 contains the attribute information which is stored in the TIFF structure and includes a File header with two IFD (sub-Image File Directory) (0th IFD and 1st IFD) at most. The 0th IFD stores the primary information while the 1st IFD may be used to record a thumbnail image [3].

The IFD in EXIF, according to the TIFF Rev. 6.0, is made by 2-byte count (number of fields), 12-byte field 12-byte field Interoperability arrays, and a 4-byte offset to the next IFD. The 12-byte are divided into the following four elements respectively [3]:

  • Bytes 0-1 Tag
  • Bytes 2-3 Type
  • Bytes 4-7 Count
  • Bytes 8-11 Value Offset

In the case of the Tags, they have a field that is identified with a unique 2-byte number. These tag numbers are in the EXIF 0th IFD and 1st IFD and are all the same as the TIFF tag numbers. The following types are used in EXIF [3]:

  • 1 = BYTE An 8-bit unsigned integer.
  • 2 = ASCII An 8-bit byte. 7-bit ASCII code and the final byte is terminated with NULL.
  • 3 = SHORT A 16-bit (2-byte) unsigned integer.
  • 4 = LONG A 32-bit (4-byte) unsigned integer.
  • 5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG is the denominator.
  • 7 = UNDEFINED An 8-bit byte that may take any value depending on the field definition.
  • 9 = SLONG A 32-bit (4-byte) signed integer (2's complement notation).
  • 10 = SRATIONAL Two SLONGs. The first SLONG is the numerator and the second SLONG is the denominator.

IPTC metadata

At the beginning of the IPTC standard was to work with text-only information. Later on, the “Information Interchange Model” (IIM), was created. With IIM, the IPTC headers were incorporated and they are the IIM metadata embedded in images. IPTC has adopted the XMP standard as the successor to the IPTC headers [1].

In the IPTC standard, each individual metadata entity is called property and they are divided into Administrative, Descriptive and Rights-related properties. This standard technical implementation works as follows [4]:

  1. The image file format specifies an outermost wrapper header
  2. The header has the Image Resource Blocks (IRB). The IRB manages a structure that contains different types of data and also could not be metadata. Each data contains a specific identifier
  3. There are 2 specifications related to the metadata fields in the IPTC IIM. One is the administrative and this specification uses the identifier that is used to identify the metadata field and the field (Tags) numbers. The second specification contains a technical description of the data stored by the field.
  4. The IPTC identifier field contains an envelope record which is a field number that is used for information such as the type of data and file format. Moreover, the data object transfer could be a photographic image, text or perhaps a combination of many types. Additional information, such as caption, news category or dateline also is included and the IIM assumes that the sender wishes to transfer this data object. When the data is sent, it does with together information such as the size of the data pertinent editorial and technical description [5].

XMP metadata

The Extensible Metadata Platform (XMP) was introduced by Adobe Systems Incorporated in 2001 and IPTC has adopted this standard. When a software program or device uses the XMP metadata it can add its own information to a digital resource and this information can be retained in the final file [6]. Also, the XMP standard uses a subset of the W3C Resource Description Framework (RDF) to be stored and is serialized in XML [1].

The XMP data model is also called an XMP packet and is a group of metadata properties. Each property has a name and a value, for example: dc:subject. The name of each property in a XMP packet has to be unique and the names of the properties shall be XML expanded names, consisting of a namespace URI and a local name. The namespace URI has not to be empty [7].

The size of the XMP packet can be at most 65502 bytes. However, it is around 2 KB typically. If the packet becomes larger than the 64 KB limit, you can divide it into a main portion (StandardXMP) and an extended portion (ExtendedXMP), and store it in multiple JPEG marker segments. By convention, an APPn marker identifies the usage with a string called namespace or signature string. The APP1 marker is used to identify the EXIF and TIFF metadata; an APP13 marker identifies the IPTC metadata that is contained in the Photoshop Image Resource (PSIR). The APP13 designates the PSIR. Another APP1 marker designates the location of the XMP packet [8].

The JPEG standard format does not oblige ordering among APPn segments, but some related standards do. For example, the APP1 segment has to be immediately after the Star of Image (SOI). Moreover, some applications suppose that the segments are in a particular order. It is better, for compatibility, to follow the next order: EXIF in the APP1 marker first, later the XMP APP1, then the PSIR APP13, followed by all other marker segments [8]

Handling multiple metadata formats

The following figure is a simplified view of metadata for which guidance is being provided by the Guidelines for handling image metadata:

Handling multiple metadata formats. Taken from Guidelines for handling image metadata


The properties described earlier have been identified by the rkinggroup.org/pdf/mwg_guidance.pdf Guidelines for handling image metadata as the most relevant in the consumer workflows today. There are some properties or tags that are defined in more than one metadata format. Actually, only four are available in EXIF, IPTC-IIM and XMP:

  • Date/Time
  • Description
  • Copyright
  • Creator

EXIF and XMP

In order to read the EXIF and XMP metadata from an image, the following figure shows an overview of how to do it:

Read EXIF and XMP metadata. Taken from Guidelines for handling image metadata

.

Moreover, there are two cases when EXIF metadata is being mapped into XMP:

  • The EXIF native properties mapped to the respective XMP properties (e.g. EXIF Copyright => XMP (dc:rights))
  • The duplicated EXIF and TIFF device properties into specific “exif:” or “tiff:” namespaces (e.g. EXIF ApertureValue => XMP (exif:ApertureValue))

On the other hand, the writing process depends on the actor's definition role: Creator or Changer.

Creator

In the case of the Creator role, the Guidelines for handling image metadata defines the following rules guidance on how to write XMP and/or EXIF metadata:

  • If a property can be stored in both locations, the XMP metadata MAY be created. Otherwise, the XMP metadata MUST be created (which is true for file formats where EXIF is not defined).
  • EXIF metadata MUST be created if the XMP metadata is not written.
Changer

In the case of the Changer role, the Guidelines for handling image metadata defines the following rules guidance on how to read and write XMP and/or EXIF metadata:

  • To consume the EXIF and XMP metadata, the Figure above should be followed.
  • When EXIF and XMP metadata are both supported in the file format, a Changer should update both values. If only one form value is updated, the other form value must be deleted.
  • If the EXIF metadata is not supported natively in a file format, in the XMP exif: and tiff: namespaces should not be any EXIF and TIFF device properties (e.g. XResolution, YResolution, WhitePoint, etc.) duplicated
  • The Changer should maintain the byte-order. For example, the EXIF metadata is a TIFF stream format. The TIFF streams must be big endian or little endian byte-order.
  • The EXIF string values should be written as UTF-8. However, to allow more interoperability, the client may write them as ASCII.
  • It should be written into the XMP standard a checksum value for EXIF/TIFF.
  • If there is no data in a file format, the Creator rules guidance should be followed.

EXIF and IMM

The next figure shows Consumer guidance on how to read IPTC-IIM related metadata.

Read IPTC-IMM and XMP metadata. Taken from Guidelines for handling image metadata


On the other hand, the writing process depends on the following actor's rules[1].

Creator
  • Unless there is a backward compatibility requirement with non-compliant Consumers that do not read XMP, a Creator should not create IPTC-IIM metadata. Otherwise, the XMP metadata should be written.
  • A Creator must produce a checksum value if IPTC-IIM and XMP metadata are both written.
Changer
  • If an IPTC-IIM value is already in the file format, both XMP and IPTC-IIM metadata values should be written back to the file by a Changer. Otherwise, only XMP should be written.
  • IPTC-IIM should be written using the Coded Character Set (1:90) as UTF-8.
  • A strong Changer should convert all property values to UTF-8 and write the corresponding identifier for UTF-8 to the 1:90 DataSet if the IPTC-IIM values have not been written as UTF-8.
  • A Changer must generate or update the checksum value If IPTC-IIM and XMP are both present, regardless of whether the values changed or not.
  • If there is no data in a file format, the Creator rules guidance should be followed.

Handling EXIF/TIFF, IPTC-IIM and XMP metadata

In the case of handling the EXIF/TIFF, IPTC-IIM and XMP metadata standards, the next rules should be followed [1]:

  • In the case of conflict between the EXIF and IPTC-IIM metadata and if the IPTC-IIM checksum matches or does not exist, a Consumer should prefer the EXIF metadata.
  • If there is a conflict between the EXIF and IPTC-IIM metadata and if the IPTC-IIM checksum does not match, a Consumer should prefer the IPTC-IIM metadata.
  • A string property must be managed as non-existent if it is comprised of only spaces or only null character.
JPEG file format

For the JPEG file format, the EXIF/TIFF, IPTC-IIM and XMP metadata standards are handled as follows:

Metadata in JPEG file format. Taken from Guidelines for handling image metadata


The tag 34664 points to the IFD structure that stores all the EXIF tags. The identifier 1028 (decimal) was assigned to a block of metadata provided in the IPTC IIM 4 format [4]. The 1061 IIM is where the checksum is stored [1].

These metadata standards should be handled as [1]:

  • EXIF and XMP should be read from the EXIF APP1 section and IPTC-IIM should be read from the image resource block (IRB) in Photoshop APP13 (1028).
  • EXIF APP1 must follow immediately after SOI. If not, the EXIF metadata may not show correctly in the current camera models.

Image Metadata handling in GStreamer

The GStreamer 1.14.5 version has an element that allows to inject metadata tags. This element is the taginject, which belongs to the GStreamer Plugins Good elements, and it does through its tags property, according to the element inspect (gst-inspect-1.0 taginject):

tags                : List of tags to inject into the target file

On the other hand, the metadata tags are managed by GStreamer Plugins Base. For example, the gstexiftag.c library handles the exif tags, while the gstxmptag.c library handles the xmp tags.

In the case of adding the tags and metadata into a JPEG image, the jifmux element can be used. According to the element inspect (gst-inspect-1.0 jifmux) description:

Description              Remuxes JPEG images with markers and tags

Adding EXIF field example

In order to add keywords or comments on an image exif metadata field, a JPEG image for this example, the UserComment tag can be used. This tag has the advantage of writing the keywords or comments without the character code limitations of the ImageDescription tag [3].

The UserComment tag is defined as UNDEFINED type [3] and the GStreamer gstexiftag.c library can handle UNDEFINED exif tag types using the write_exif_undefined_tag_from_taglist function. So, based on the UNDEFINED type definition, the UserComment documentation specificities that there needs 8-byte padding and works with UTF-8 encoding standard. In order to get the UTF-8 string, the GLib g_strdup_printf function can be used.

However, the GStreamer gstexiftag.c library does not support the UserComment tag specifically. So, here is an explanation of how to add this tag:

  1. Add the EXIF Tag Hexadecimal code definition. This Hexadecimal code can be found in exif-tag.h File Reference.
  2. Identify the tag group. In the case of the UserComment the tag group belongs to the ExifIFD group [9]. So, add the tag into the tag_map_exif structure.
  3. Add the logic code according to the Exchangeable image file format for digital still cameras: EXIF Version 2.32 standard (8-byte padding and UTF-8 encoding string).
  4. Add the logic to GStreamer to support a list of strings.

The following code shows the implementation of the UserComment to support more than one string value:

diff --git a/gst-libs/gst/tag/gstexiftag.c b/gst-libs/gst/tag/gstexiftag.c
index b615779..57c8270 100644
--- a/gst-libs/gst/tag/gstexiftag.c
+++ b/gst-libs/gst/tag/gstexiftag.c
@@ -318,6 +318,7 @@ EXIF_DESERIALIZATION_FUNC (add_to_pending_tags);
 #define EXIF_TAG_CONTRAST 0xA408
 #define EXIF_TAG_SATURATION 0xA409
 #define EXIF_TAG_SHARPNESS 0xA40A
+#define EXIF_TAG_USER_COMMENT 0x9286
 
 /* IFD pointer tags */
 #define EXIF_IFD_TAG 0x8769
@@ -373,6 +374,8 @@ static const GstExifTagMatch tag_map_exif[] = {
         EXIF_TYPE_SHORT, 0, serialize_exposure_program,
       deserialize_exposure_program},
 
+  {GST_TAG_COMMENT, EXIF_TAG_USER_COMMENT, EXIF_TYPE_UNDEFINED, 0, NULL, NULL},
+
   /* don't need the serializer as we always write the iso speed alone */
   {GST_TAG_CAPTURING_ISO_SPEED, EXIF_TAG_PHOTOGRAPHIC_SENSITIVITY,
         EXIF_TYPE_SHORT, 0, NULL,
@@ -917,25 +920,46 @@ static void
 write_exif_undefined_tag_from_taglist (GstExifWriter * writer,
     const GstTagList * taglist, const GstExifTagMatch * exiftag)
 {
-  const GValue *value;
+  const GValue *value = NULL;
   GstMapInfo info;
   guint8 *data = NULL;
   gsize size = 0;
   gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag);
   GstSample *sample = NULL;
   GstBuffer *buf = NULL;
+  gint i = 0;
+  gchar *value_str = NULL;
+  gchar *str = NULL;
+  gchar *temp_str = NULL;
+  gboolean cleanup = FALSE;
 
-  if (tag_size != 1) {
-    GST_WARNING ("Only the first item in the taglist will be serialized");
-    return;
+  if (strcmp (exiftag->gst_tag, GST_TAG_COMMENT) == 0) {
+    cleanup = TRUE;
+    for (i = 0; i < tag_size; i++) {
+      value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, i);
+      value_str = (gchar *) g_value_get_string (value);
+      if (str && value_str) {
+        temp_str = g_strdup_printf ("%s, %s", str, value_str);
+        g_free (str);           /* Frees the str and the previous temp_str memory allocation. Since both are pointing to the same memory space */
+        str = temp_str;
+      } else if (value_str && !str) {
+        /* Add 8 bit padding to the first value. It is needed according to the standard */
+        str = g_strdup_printf ("%-7s %s", "", value_str);
+      }
+    }
+  } else {
+    /* Keep other tags to get only the first item in the taglist */
+    value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0);
+    /* Handle string values and continue using the str variable */
+    if (G_VALUE_TYPE (value) == G_TYPE_STRING) {
+      str = (gchar *) g_value_get_string (value);
+    }
   }
 
-  value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0);
-
   /* do some conversion if needed */
   switch (G_VALUE_TYPE (value)) {
     case G_TYPE_STRING:
-      data = (guint8 *) g_value_get_string (value);
+      data = (guint8 *) str;    /* The str variable is encoded in a UTF-8 string already. Does not need conversion */
       size = strlen ((gchar *) data);   /* no need to +1, undefined doesn't require it */
       break;
     default:
@@ -960,6 +984,11 @@ write_exif_undefined_tag_from_taglist (GstExifWriter * writer,
 
   if (buf)
     gst_buffer_unmap (buf, &info);
+
+  /* Only free the str variable if the g_strdup_printf function was used */
+  if (cleanup) {
+    g_free (str);
+  }
 }
 
 static void

GStreamer pipeline Example

gst-launch-1.0 videotestsrc num-buffers=1 ! jpegenc ! taginject tags="comment=\{\"testone\",\"image\"\}" ! jifmux ! filesink location=test.jpeg

To add some GStreamer debugging, the following environment variables could be set at the beginning of the pipeline:

GST_DEBUG=2,*tag*:8,*jifmux*:8

The output messages should be similar to the following:

GST_DEBUG=2,*tag*:8,*jifmux*:8 gst-launch-1.0 videotestsrc num-buffers=1 ! jpegenc ! taginject tags="comment=\{\"testone\",\"image\"\}" ! jifmux ! filesink location=/tmp/test.jpeg
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
0:00:00.364279713 24340   0x55a8d43680 DEBUG              taginject gsttaginject.c:147:gst_tag_inject_transform_ip: tag event :taglist, comment=(string){ testone, image };
0:00:00.364378657 24340   0x55a8d43680 INFO                  jifmux gstjifmux.c:322:gst_jif_mux_sink_event:<jifmux0> Merge mode set to: 5
0:00:00.364456225 24340   0x55a8d43680 LOG                   jifmux gstjifmux.c:390:gst_jif_mux_parse_image:<jifmux0> Received buffer of size: 9423
0:00:00.364478497 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:412:gst_jif_mux_parse_image:<jifmux0> marker = d8
0:00:00.364497345 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:430:gst_jif_mux_parse_image:<jifmux0> marker = e0, size = 16
0:00:00.364514177 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:430:gst_jif_mux_parse_image:<jifmux0> marker = db, size = 67
0:00:00.364531169 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:430:gst_jif_mux_parse_image:<jifmux0> marker = db, size = 67
0:00:00.364547489 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:430:gst_jif_mux_parse_image:<jifmux0> marker = c0, size = 17
0:00:00.364563745 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:430:gst_jif_mux_parse_image:<jifmux0> marker = c4, size = 31
0:00:00.364580033 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:430:gst_jif_mux_parse_image:<jifmux0> marker = c4, size = 181
0:00:00.364595873 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:430:gst_jif_mux_parse_image:<jifmux0> marker = c4, size = 31
0:00:00.364612257 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:430:gst_jif_mux_parse_image:<jifmux0> marker = c4, size = 181
0:00:00.364674273 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:430:gst_jif_mux_parse_image:<jifmux0> marker = da, size = 12
0:00:00.364693985 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:457:gst_jif_mux_parse_image:<jifmux0> scan data, size = 8798
0:00:00.364708353 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:417:gst_jif_mux_parse_image:<jifmux0> marker = d9
0:00:00.364724257 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:512:gst_jif_mux_mangle_markers:<jifmux0> found APP0 JFIF
0:00:00.364748609 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:631:gst_jif_mux_mangle_markers:<jifmux0> Tags to be serialized taglist, comment=(string){ testone, image };
0:00:00.364993537 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:729:gst_jif_mux_mangle_markers:<jifmux0> set COM marker to 'testone'
0:00:00.365020001 24340   0x55a8d43680 INFO                  jifmux gstjifmux.c:770:gst_jif_mux_recombine_image:<jifmux0> old size: 9423, new size: 12355
0:00:00.365052801 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = d8, size = 2
0:00:00.365070817 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = e0, size = 16
0:00:00.365087809 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = e1, size = 98
0:00:00.365104385 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = e1, size = 2818
0:00:00.365124641 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = fe, size = 10
0:00:00.365140417 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = db, size = 67
0:00:00.365156129 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = db, size = 67
0:00:00.365171393 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = c0, size = 17
0:00:00.365186529 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = c4, size = 31
0:00:00.365201697 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = c4, size = 181
0:00:00.365217634 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = c4, size = 31
0:00:00.365232866 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = c4, size = 181
0:00:00.365248418 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = da, size = 12
0:00:00.365263074 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:798:gst_jif_mux_recombine_image:<jifmux0> scan data, size = 8798
0:00:00.365286274 24340   0x55a8d43680 DEBUG                 jifmux gstjifmux.c:790:gst_jif_mux_recombine_image:<jifmux0> marker = d9, size = 2

Image Metadata verification tools

In order to read, write and edit the metadata in a file the following tools could be used:

ExifTool

To install in a Linux environment, use the following command:

sudo apt install libimage-exiftool-perl

In order to verify the metadata write into the JPEG image in the GStreamer pipeline example section the following commands can be used:

exiftool -g -H test.jpeg

Which the -g and -H options are [10]:

  • -g Organize output by tag group
  • -H Show tag ID numbers in hexadecimal

The GStreamer pipeline example output should be similar to the following:

exiftool -g -H test.jpeg 
---- ExifTool ----
     - ExifTool Version Number         : 10.80
---- File ----
     - File Name                       : test.jpeg
     - Directory                       : .
     - File Size                       : 12 kB
     - File Modification Date/Time     : 2023:09:07 12:16:24-05:00
     - File Access Date/Time           : 2023:09:07 12:16:41-05:00
     - File Inode Change Date/Time     : 2023:09:07 12:16:24-05:00
     - File Permissions                : rw-r--r--
     - File Type                       : JPEG
     - File Type Extension             : jpg
     - MIME Type                       : image/jpeg
     - Exif Byte Order                 : Little-endian (Intel, II)
     - Comment                         : testone
     - Image Width                     : 320
     - Image Height                    : 240
     - Encoding Process                : Baseline DCT, Huffman coding
     - Bits Per Sample                 : 8
     - Color Components                : 3
     - Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
---- JFIF ----
0x0000 JFIF Version                    : 1.01
0x0002 Resolution Unit                 : None
0x0003 X Resolution                    : 1
0x0005 Y Resolution                    : 1
---- EXIF ----
0x9286 User Comment                    : testone, image
0x9000 Exif Version                    : 0230
0xa000 Flashpix Version                : 0100
---- XMP ----
     - XMP Toolkit                     : GStreamer
---- Composite ----
     - Image Size                      : 320x240
     - Megapixels                      : 0.077

Also, the -G can be used in order to print the group name for each tag. Use G1 instead of g in order to get the family 1 group name (ie. the location) of each tag:

[ExifIFD]       0x9286 User Comment                    : testone, image

exiv2

To install in a Linux environment, use the following command:

sudo apt install exiv2

In order to verify the metadata write into the JPEG image in the GStreamer pipeline example section the following commands can be used [11]:

  • Simply command to print the image metadata:
exiv2 test.jpeg
exiv2 test.jpeg 
File name       : test.jpeg
File size       : 12355 Bytes
MIME type       : image/jpeg
Image size      : 320 x 240
Camera make     : 
Camera model    : 
Image timestamp : 
Image number    : 
Exposure time   : 
Aperture        : 
Exposure bias   : 
Flash           : 
Flash bias      : 
Focal length    : 
Subject distance: 
ISO speed       : 
Exposure mode   : 
Metering mode   : 
Macro mode      : 
Image quality   : 
Exif Resolution : 
White balance   : 
Thumbnail       : None
Copyright       : 
Exif comment    : testone, image
  • Print the exif metadata specifically:
exiv2 -PE test.jpeg
exiv2 -PE test.jpeg
Exif.Image.ExifTag                           Long        1  26
Exif.Photo.UserComment                       Undefined  22  testone, image
Exif.Photo.ExifVersion                       Undefined   4  2.30
Exif.Photo.FlashpixVersion                   Undefined   4  1.00
  • Print the hexadecimal exif metadata:
exiv2 -ph test.jpeg
exiv2 -ph test.jpeg
0x8769 Image        ExifTag                     Long        1   4
  0000  1a 00 00 00                                      ....

0x9286 Photo        UserComment                 Undefined  22  22
  0000  20 20 20 20 20 20 20 20 74 65 73 74 6f 6e 65 2c          testone,
  0010  20 69 6d 61 67 65                                 image

0x9000 Photo        ExifVersion                 Undefined   4   4
  0000  30 32 33 30                                      0230

0xa000 Photo        FlashpixVersion             Undefined   4   4
  0000  30 31 30 30                                      0100


References



For direct inquiries, please refer to the contact information available on our Contact page. Alternatively, you may complete and submit the form provided at the same link. We will respond to your request at our earliest opportunity.


Links to RidgeRun Resources and RidgeRun Artificial Intelligence Solutions can be found in the footer below.