app, libgimpbase: add creation date/time metadata...

when creating a new image.

We add a new function `gimp_metadata_set_creation_date` to
`libgimpbase/gimpmetadata` to handle setting all relevant
metadata tags.

We add a local function `gimp_image_new_add_creation_metadata` to
add the creation date metadata to relevant functions that create
new images.
We write tags for both the creation date and several modified dates
for IPTC, XMP and Exif metadata. All these use different ways to
express date/time and timezones and I can already see we need to have
another look at other places where we handle modified dates.

This solves the second part of #7287, adding metadata about the
date/time a new image was created.
This commit is contained in:
Jacob Boerema 2025-01-13 16:15:27 -05:00
parent 4ff4ce2870
commit 6b10cce682
4 changed files with 128 additions and 0 deletions

View File

@ -43,6 +43,7 @@
#include "gimpimage.h"
#include "gimpimage-color-profile.h"
#include "gimpimage-colormap.h"
#include "gimpimage-metadata.h"
#include "gimpimage-new.h"
#include "gimpimage-undo.h"
#include "gimplayer.h"
@ -101,6 +102,26 @@ gimp_image_new_set_last_template (Gimp *gimp,
G_OBJECT (gimp->image_new_last_template), 0);
}
void
gimp_image_new_add_creation_metadata (GimpImage *image)
{
GimpMetadata *metadata;
metadata = gimp_image_get_metadata (image);
if (! metadata)
{
g_critical ("Metadata not found. Should not happen!");
}
else
{
GDateTime *datetime;
datetime = g_date_time_new_now_local ();
gimp_metadata_set_creation_date (metadata, datetime);
g_date_time_unref (datetime);
}
}
GimpImage *
gimp_image_new_from_template (Gimp *gimp,
GimpTemplate *template,
@ -182,6 +203,8 @@ gimp_image_new_from_template (Gimp *gimp,
gimp_image_add_layer (image, layer, NULL, 0, FALSE);
gimp_image_new_add_creation_metadata (image);
gimp_image_undo_enable (image);
gimp_image_clean_all (image);
@ -285,6 +308,8 @@ gimp_image_new_from_drawable (Gimp *gimp,
gimp_image_add_layer (new_image, new_layer, NULL, 0, TRUE);
gimp_image_new_add_creation_metadata (new_image);
gimp_image_undo_enable (new_image);
return new_image;
@ -535,6 +560,8 @@ gimp_image_new_from_drawables (Gimp *gimp,
gimp_image_new_copy_drawables (image, drawables, new_image, tag_copies, NULL, NULL, NULL, NULL);
gimp_image_new_add_creation_metadata (new_image);
gimp_image_undo_enable (new_image);
return new_image;
@ -581,6 +608,8 @@ gimp_image_new_from_component (Gimp *gimp,
gimp_image_add_layer (new_image, layer, NULL, 0, TRUE);
gimp_image_new_add_creation_metadata (new_image);
gimp_image_undo_enable (new_image);
return new_image;
@ -630,6 +659,8 @@ gimp_image_new_from_buffer (Gimp *gimp,
gimp_image_add_layer (image, layer, NULL, 0, TRUE);
gimp_image_new_add_creation_metadata (image);
gimp_image_undo_enable (image);
return image;
@ -691,6 +722,8 @@ gimp_image_new_from_pixbuf (Gimp *gimp,
gimp_image_add_layer (new_image, layer, NULL, 0, TRUE);
gimp_image_new_add_creation_metadata (new_image);
gimp_image_undo_enable (new_image);
return new_image;

View File

@ -116,6 +116,7 @@ EXPORTS
gimp_metadata_serialize
gimp_metadata_set_bits_per_sample
gimp_metadata_set_colorspace
gimp_metadata_set_creation_date
gimp_metadata_set_from_exif
gimp_metadata_set_from_iptc
gimp_metadata_set_from_xmp

View File

@ -1681,6 +1681,98 @@ gimp_metadata_set_resolution (GimpMetadata *metadata,
"Exif.Image.ResolutionUnit", buffer, NULL);
}
/**
* gimp_metadata_set_creation_date:
* @metadata: A #GimpMetadata instance.
* @datetime: A #GDateTime value
*
* Sets `Iptc.Application2.DateCreated`, `Iptc.Application2.TimeCreated`,
* `Exif.Image.DateTime`, `Exif.Image.DateTimeOriginal`,
* `Exif.Photo.DateTimeOriginal`, `Exif.Photo.DateTimeDigitized`,
* `Exif.Photo.OffsetTime`, `Exif.Photo.OffsetTimeOriginal`,
* `Exif.Photo.OffsetTimeDigitized`, `Xmp.xmp.CreateDate`, `Xmp.xmp.ModifyDate`,
* `Xmp.xmp.MetadataDate`, `Xmp.photoshop.DateCreated` of @metadata.
*
* Since: 3.0
*/
void
gimp_metadata_set_creation_date (GimpMetadata *metadata,
GDateTime *datetime)
{
gchar *datetime_buf = NULL;
GExiv2Metadata *g2metadata = GEXIV2_METADATA (metadata);
g_return_if_fail (GIMP_IS_METADATA (metadata));
/* IPTC: set creation date and time; there is no tag for modified date/time. */
datetime_buf = g_date_time_format (datetime, "%Y-%m-%d");
gexiv2_metadata_try_set_tag_string (g2metadata,
"Iptc.Application2.DateCreated",
datetime_buf, NULL);
g_free (datetime_buf);
/* time and timezone */
datetime_buf = g_date_time_format (datetime, "%T\%:z");
gexiv2_metadata_try_set_tag_string (g2metadata,
"Iptc.Application2.TimeCreated",
datetime_buf, NULL);
g_free (datetime_buf);
/* Exif: Exif.Image.DateTime = Modified datetime
* Exif.Image.DateTimeOriginal and Exif.Photo.DateTimeOriginal = When the
* original image data was generated.
* Exif.Photo.DateTimeDigitized = when the image was stored as digital data.
*/
datetime_buf = g_date_time_format (datetime, "%Y:%m:%d %T");
gexiv2_metadata_try_set_tag_string (g2metadata,
"Exif.Image.DateTime",
datetime_buf, NULL);
gexiv2_metadata_try_set_tag_string (g2metadata,
"Exif.Image.DateTimeOriginal",
datetime_buf, NULL);
gexiv2_metadata_try_set_tag_string (g2metadata,
"Exif.Photo.DateTimeOriginal",
datetime_buf, NULL);
gexiv2_metadata_try_set_tag_string (g2metadata,
"Exif.Photo.DateTimeDigitized",
datetime_buf, NULL);
g_free (datetime_buf);
/* Timezone is separate */
datetime_buf = g_date_time_format (datetime, "\%:z");
gexiv2_metadata_try_set_tag_string (g2metadata,
"Exif.Photo.OffsetTime",
datetime_buf, NULL);
gexiv2_metadata_try_set_tag_string (g2metadata,
"Exif.Photo.OffsetTimeOriginal",
datetime_buf, NULL);
gexiv2_metadata_try_set_tag_string (g2metadata,
"Exif.Photo.OffsetTimeDigitized",
datetime_buf, NULL);
g_free (datetime_buf);
/* XMP: Xmp.photoshop.DateCreated = date when the original image was
* taken, this can be before Xmp.xmp.CreateDate. */
datetime_buf = g_date_time_format (datetime, "%Y:%m:%dT%T\%:z");
gexiv2_metadata_try_set_tag_string (g2metadata,
"Xmp.xmp.CreateDate",
datetime_buf, NULL);
gexiv2_metadata_try_set_tag_string (g2metadata,
"Xmp.xmp.ModifyDate",
datetime_buf, NULL);
gexiv2_metadata_try_set_tag_string (g2metadata,
"Xmp.xmp.MetadataDate",
datetime_buf, NULL);
gexiv2_metadata_try_set_tag_string (g2metadata,
"Xmp.photoshop.DateCreated",
datetime_buf, NULL);
g_free (datetime_buf);
}
/**
* gimp_metadata_get_colorspace:
* @metadata: A #GimpMetadata instance.

View File

@ -142,6 +142,8 @@ void gimp_metadata_set_resolution (GimpMetadata *metada
gdouble xres,
gdouble yres,
GimpUnit *unit);
void gimp_metadata_set_creation_date (GimpMetadata *metadata,
GDateTime *datetime);
GimpMetadataColorspace
gimp_metadata_get_colorspace (GimpMetadata *metadata);