MetaImage Module and Workflow

The MetaImage class is meant to act as an abstraction layer for between high level processes like image sequence editing and lower level processes like parsing image files. It presently only supports DNG files but the intention was to allow it to be expanded to be able to handle any kind of image file.

Note

Since the MetaImage class and module is an abstraction layer intended to allow expansion beyond DNG files, but DNG files are all that’s currently supported, their APIs are presently very similar, but if more file types are supported that could change as functionality increases.

Usage

Example: Getting the top left quarter of the image

In this example, a piece of the total image is rendered and returned. Since the area to render is input at [0, 0, 0.5, 0.5], the rendered portion is from the top left corner to the center of the image.

from brilliantimagery.meta_image import MetaImage

meta_image = MetaImage('path/to/image.file')

image = meta_image.get_image([0, 0, 0.5, 0.5], 'RAW')

Example: Get, update, and save XMP data

Input:

from brilliantimagery.meta_image import MetaImage

meta_iamge = MetaImage('path/to/image.file')

val = meta_image.get_xmp_attribute(b'xmp:attr')

print(f'Was: {val}')

val += 5

print(f'Is: {val}')

meta_image.set_xmp_attribute(b'xmp:attr', val)
meta_image.store_xmp_field()
meta_image.save()

val = meta_image.get_xmp_attribute(b'xmp:attr')

print(f'Is still: {val}')

Returns:

Was: 5.5
Is: 10.5
Is still: 10.5

API

class brilliantimagery.meta_image.MetaImage(path: str)

A representation of an image file.

Only DNG image files are presently supported.

Arguments:

path (string): The path to an existing image file file.

Attributes:

image (DNG): A representation of the underlying image file brightness (float): A value representing the brightness of the image.

get_brightness(rectangle=None, image=None)

Gets a reference brightness value for the image.

Gets the median green value for the image.

Parameters
  • rectangle (list[int or float]) –

    The bounding box of the portion of the image that’s to be rendered. In the format X1, Y1, X2, Y2 where:

    • X1 is the x position of the top left corner,

    • Y1 is the y position of the top left corner,

    • X2 is the x position of the bottom right corner,

    • Y2 is the y position of the top right corner.

    The input values can either be in fractions of the way across the image from the origin, or pixels from the origin. The top left corner of the cropped area is assumed to be the origin. If no crop is applied by the user than the DefaultCropOrigin field data is used as the origin.

  • image (Numpy.ndarray) –

    A 3D float array holding the rendered image.

    • The first dimension represents the color channels: Red, Green, Blue at indices 0, 1, and 2 respectively.

    • The second represents the width.

    • The third represents the height.

Returns

The median green value from the image as a float in the range from 0 to 1.

Return type

float

get_capture_datetime()

Gets when the image was captured.

The return value may be formatted as a datetime or unix time stamp depending on the available information. The format should be consistent between images captured on the same camera and processed with the same workflow.

Returns

A creation time.

Return type

str

get_default_shape()

Gets the dimensions of the raw image, before it’s edited or cropped.

Dimensions are in units of pixels.

Returns

A list of ints where the first is the width and the second is the length (height) of the image.

Return type

list[int, int]

get_image(rectangle=[0.0, 0.0, 1.0, 1.0], sub_image_type='RAW')

Get the desired portion of the desired reference image.

No transforms such as white balancing or exposure compensation are performed so the image may not look as expected (they’re often too green).

The rendering algorithm is relatively rudimentary so the results will be less refined than some other renderers.

Note that the output is a float in the range of 0 to 1 so for many applications it’ll have to be scaled.

While many (most?) cameras are, or could with relative ease be supported, some Fuji cameras (and presumably others) will require further development.

Parameters
  • rectangle (list[int or float]) –

    The bounding box of the portion of the image that’s to be rendered. In the format X1, Y1, X2, Y2 where:

    • X1 is the x position of the top left corner,

    • Y1 is the y position of the top left corner,

    • X2 is the x position of the bottom right corner,

    • Y2 is the y position of the top right corner.

    The input values can either be in fractions of the way across the image from the origin, or pixels from the origin. The top left corner of the cropped area is assumed to be the origin. If no crop is applied by the user than the DefaultCropOrigin field data is used as the origin.

  • sub_image_type (str) –

    selects which sub-image to return from the file.

    RAW to get the original, raw, image.

    thumbnail to get the thumbnail if present.

Returns

A 3D float array holding the rendered image.

  • The first dimension represents the color channels: Red, Green, Blue at indices 0, 1, and 2 respectively.

  • The second represents the width.

  • The third represents the height.

Return type

Numpy.ndarray

get_relevant_xmp_attributes()

Gets the inclusive set of relevant XMP attributes.

These are attributes that are edited with photo editing software such as exposure, rating, and saturation. Irrelevant attributes, from a photo editing perspective, such as when the photo was taken, are not returned.

Returns

A dict of the below key value pairs:

- key is the property name.
- value is a namedtuple with the follow properties.
- n_decimal_places: int - The number of decimal places to use when storing the property value.
- default_value: str - The default value in Lightroom.
- is_vector: bool - True if it always has a sign in the XMP data, otherwise False.
- is_ramped: bool - True if it should be linearly ramped (i.e. Temperature), otherwise False (i.e. Rating)

Return type

dict(bytes: namedtuple(int, str, bool, bool))

get_rendered_shape()

Gets the dimensions of the raw image, as cropped and rendered.

Dimensions are in units of pixels.

Returns

A list of ints where the first is the width and the second is the length (height) of the image.

Return type

list[int, int]

get_xmp()

Gets the stored XMP data from the represented dng file.

The XMP data holds all of the edits that have been made in Lightroom.

Returns

The xmp data as a dict with the keys being the properties as found in the XMP data and values being the associated values as floats.

Return type

dict[bytes, float]

get_xmp_attribute(xmp_attribute: Union[bytes, str])

Gets the value of an XMP attribute.

Only works for attributes with numeric values.

Parameters

xmp_attribute (bytes) – The attribute to be interrogated. Must include the full attribute name, the part before and after the :`

Returns

The value of the attribute if it’s present and numeric, otherwise None.

Return type

float or None

property is_key_frame

Says whether or not an image is a reference frame.

For timelapse sequences, specifies whether or not the given image is intended to be used as a reference frame. This is determined by the image star rating and whether or not it matches the number of stars that a DNG image must have to be considered a reference frame, 3 by default.

Returns

True if it’s a reference frame, otherwise false.

Return type

bool

save()

Overwrites the dng’s XMP data with the updated XMP data.

Returns

None

set_xmp_attribute(xmp_attribute: Union[bytes, str], value: Union[int, float, str])

Updates the stored value of an XMP attribute.

Cannot update attributes that aren’t already present. If an attribute wasn’t previously present it can’t be updated.

Only updates the representation in the DNG object. DNG.store_xmp_field() and DNG.save() have to be called to permanently save the updated values.

Parameters
  • xmp_attribute – The XMP attribute to be updated. Should be a key from the _dng_constants.XMP_TAGS dict

  • value (int, float, or str) – The number to be assigned to the attribute.

Returns

True if it’s successful, False if it isn’t, presumably because the attribute isn’t present or the value was already stored.

Return type

bool

store_xmp_field()

Consolidate updated XMP attributes in the XMP data.

If this isn’t called, the XMP data won’t be updated in the file even if DNG.save() is called.

Returns

None