Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow programatically reading / setting output color profile of an image to be exported #522

Open
koto opened this issue Sep 23, 2024 · 3 comments

Comments

@koto
Copy link
Contributor

koto commented Sep 23, 2024

Forked from pixls.us thread:

In a script, I'm using the following code to export an image to JPG:

local exporter = dt.new_format("jpeg")
exporter.quality = 95
exporter:write_image(src, dest)

That code is dependent on the export module's output color profile currently selected in the UI. I would like to either force a specific profile (let's say Display P3 RGB), or detect when an invalid profile (for my purpose) is used, to be able to warn the user. My options with the current API are:

  1. dt.gui.action("lib/export/profile", 0, "selection", "first", 0.0) + dt.gui.action("lib/export/profile", 0, "selection", "next", 10.0) as Display P3 RGB is currently the 11th one displayed; that's hardcoded in colorspaces.c.

    Pro: Unobtrusive.
    Con: Depends on DT internals without their proper representation through the API. If DT profile order ever changes, the script forcefully selects a different profile.

  2. dt.gui.action("lib/export/profile", 0, "selection", "popup", 0.0)

    Pro: Doesn't depend on DT internals, user could select their own ICC profiles too.
    Con: Obtrusive; user is prompted to the action even if the current settings are correct, they are also asked to select the only correct option.

  3. Export, then check the resulting file metadata, and error out post factum.
    Pro: Unobtrusive.
    Con: Suboptimal UX, as I cannot prevent the error from happening, or implement input data validation before triggering the action. Possibly the metadata won't be there if export doesn't have the EXIF.

  4. Export outside of DT
    Pro: Total control over the output.
    Con: Needs an intermediary export in DT to a format that isn't sensitive to color profile (does it even exist?) to retain changes done to the RAW in DT, like cropping etc.

All of the workarounds above would not be needed if the Lua API allowed for:

  • Setting output color profile in dt_imageio_module_format_t.write_image, or
  • Reading/setting output color profile of dt_lua_image_t (this might be through EXIF image information editor #414). I could then use image settings profile in export, which is the first option in the combobox, or
  • Reading/setting the combobox options by their name in export's profile combobox (the item: prefix doesn't seem to work there)
@koto
Copy link
Contributor Author

koto commented Sep 23, 2024

The current export output color profile is also stored in a DT preference (plugins/lighttable/export/icctype=26 for Display P3 RGB), but I can't read core DT preferences from Lua (only enumerate them with dartktable.preferences.get_keys).

Edit: scratch that,

dt.preferences.read("darktable", "plugins/lighttable/export/icctype", "integer") -- 26

seems to work.

@wpferguson
Copy link
Member

Reading code I find...

// TODO: expose these to the user!
 gboolean high_quality = dt_conf_get_bool("plugins/lighttable/export/high_quality_processing");
 gboolean export_masks = dt_conf_get_bool("plugins/lighttable/export/export_masks");
 // TODO: expose icc overwrites to the user!
 dt_colorspaces_color_profile_type_t icc_type = dt_conf_get_int("plugins/lighttable/export/icctype");
 const char *icc_filename = dt_conf_get_string_const("plugins/lighttable/export/iccprofile");

Reading/setting output color profile of dt_lua_image_t

Not part of the image. The image record has a colorspace entry, but is SRGB or Adobe RGB as used by the camera.

Reading/setting the combobox options by their name.

They are translated, so the comparison code would have to be translated too. We are working on getting the Lua scripts to use darktable translation, so this may be possible in the future. It would probably require changes to dt.gui.action() to expose the information.

For the options above...

  • option 2 is a minefield. I could see issue after issue about the wrong output colorspace because the user forgot to reset it, or didn't pick the correct one.
  • option 3 - I don't think the user would be happy to go through the whole export process only to get an error. Then they would have to go to option 2 and play in the minefield.
  • option 4 - with all the package formats (appimage, flatpak, snap, etc) that don't play well with anything outside the package, this probably wont end well either

Which leaves option 1 (at least for now)...

  • The options are hardcoded, but they only change possibly twice per year (June/December releases). Even allowing programmatic access, we would still have to be aware of this and allow for it.
  • We can restrict the code via API, i.e. an API 9.3.0 version and an API 9.4.0 version, etc.
  • we can get the current setting (dt.gui.action("lib/export/profile")), then calculate the change and change to the profile we need, then change back to the original profile after we've exported.

@koto
Copy link
Contributor Author

koto commented Sep 25, 2024

Which leaves option 1 (at least for now)...

That's what I did in the end in 6a835ce, with a slightly improved method. I go to first option, and then trigger next + read off config value, until I get the hardcoded 26; so the code only depends on a few const values that are very unlikely to change, and I don't have to rely on the ordering in the combobox. I only have to sleep 10ms after each step, so that's quite all right for my purpose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants