TIP 529: Add metadata dict property to tk photo image

Bounty program for improvements to Tcl and certain Tcl packages.
Author:         Harald Oehlmann <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Created:        07-Dec-2018
Keywords:       Tk, image
Tcl-Version:    8.7
Tk-Branch:     tip-529-image-metadata


An additional property is proposed for photo images to hold a dictionary with image metadata:

myimage cget -metadata
myimage configure -metadata [dict create DPI 300.0]

The content of the dictionary is initialized on image load and used on image save.


Image files may contain a lot of metadata like resolution, comments, GPS location etc. This metadata should be accessable and setable for the following aims:

image resolution

This TIP specially targets the resolution (DPI) value of the image.

The image resolution included in an image file is crucial for its usage, as many applications (word & co.) use this field to calculate a default size. One may enjoy, that image files used in pdf4tcl are automatically scaled at the right resolution (e.g. the resolution saved in the image file).

This information is included in png files (supported by tk core) and many other image formats included in the Img patch.

I authored an extension to the Img patch to specify the dpi field of a bmp file on file writing. The syntax was accorded with Jeff Hobbs:

myimage write file.bmp -format [list bmp -resolution 300 i]

This may be expressed (when all packages are adopted) by:

myimage configure -metadata [dict create DPI 300.0]
myimage write file.bmp

I was just contacted by Paul Obermaier (TkImg maintainer) to extend the upper patch to other image formats. This motivated me again to work on the implementation.

XMP data

Photo images may contain an XMP data structure which may hold structured data. The aim is to make this data accessible. The parsing of the XML structure is not part of this TIP and may be done by other packages.

Intermediate Image representation

The TIP should set the base to hold an intermediate image representation (The concrete solution may follow by another TIP).

The application is within the current SVG implementation included in Tk8.7a3.

The used svg routines from the nanosvg project split svg processing into two steps:

When svg files are loaded by:

image create photo i1 -file test.svg -format {svg -scaletoheight 16}

then the file is accessed and the xml data loaded and processing step 1 and 2 is performed.

When the image is scaled by:

i1 configure -format {svg -scaletoheight 32}

then the same steps are performed as on image load, while only step 2 would be necessary. The performance is poor and the file must still be available.

The idea is to store the binary representation of the splines (result of processing step 1) as a key in the -metadata dict (say splinesblob) and to acheve to only perform step 2 on scaling.

In addition, svg image may even be "compiled" to the metadata structure, so the following command may work:

image create i1 -metadata {splineblob ...} -format {svg -scaletoheight 32}

This will only work within the same patchlevel of TK, as the format may change, but it may be useful for example when packing to a starkit.

In my talk on ETCL 2019, I showed an Android GUI where buttons may be scaled by a pinch to zoom gesture. The current performance is quite poor.

Comment data

A comment may be used to save custom data in the image file.

An example is a vision automation project where a test procedure is connected to each image. My solution is to use GIF images and to store the test procedure (a TCL script) in the gif comment.


Metadata Dict

The propery "-metadata" is added to each image. It contains a dictionary, where the keys of the dictionary are specific to each photo image format.

The following default keys are used by Tk's built in photo image formats, if the corresponding data is present:

Key Description Example image formats
DPI Image resolution png
Comment Text comment gif
XMP xmp image data gif,png

If a particular image does not specify any keys (whether during creation or otherwise) then the dictionary will be empty.


The following commands are directly concerned:

image create photo myimage -metadata $metadict
myimage cget -metadata
myimage configure -metadata $metadict

It is also OK to store application data related to the image within the property dict. A widget may store special properties. Tk will store and return values with unknown keys, but otherwise will ignore them.

Any load and save command may use the content of the metadata dict. This may be an ongoing process, specially within the Img patch.

The commands are:

image create photo myimage -file myfile.bmp
myimage configure -file myfile.bmp
myimage write file.bmp

The image create and file loading functions recreate the metadata dict. Any current contents is lost.

The write method uses any dict keys it knows. Any unknown dict keys are ignored.

C interface: only use metadata dict get and set functions

Two new stub table functions are added:

Tcl_Obj * Tk_PhotoGetMetadata(Tk_PhotoHandle handle)

void Tk_PhotoSetMetadata(Tk_PhotoHandle handle, Tcl_Obj *metadata)

This works well for image read. The function "Tk_PhotoSetMetadata" is called within the image read function.

On image write, the command must be extended to contain the metadata dict. The current function is:

static int CommonWriteGIF(Tcl_Interp *interp,
        const char *fileName,
        WriteBytesFunc *writeProc,
        Tcl_Obj *format,
        Tk_PhotoImageBlock *blockPtr);

This is an unsolved issue.


Implementation started with the tag tip-529-image-metadata.

Rejected Alternatives



This document has been placed in the public domain.