-
Notifications
You must be signed in to change notification settings - Fork 115
/
Copy pathautostyle.lua
200 lines (166 loc) · 6.99 KB
/
autostyle.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
--[[
Autostyle
Automatically apply a given style when an exif tag is present in the file. This tagged is checked with exiftool, in order to be able to match very exotic tags.
I wrote this initially to be able to apply a style to compensate for Auto-DR from my Fujifilm camera
AUTHOR
Marc Cousin (cousinmarc@gmail.com)
INSTALATION
* copy this file in $CONFIGDIR/lua/ where CONFIGDIR
is your darktable configuration directory
* add the following line in the file $CONFIGDIR/luarc
require "autostyle"
USAGE
* set the exif configuration string in your lua configuration
mine, for instance, is AutoDynamicRange=200%=>DR200"
meaning that I automatically want to apply my DR200 style on all
images where exiftool returns '200%' for the AutoDynamicRange tag
* if you want to be able to apply it manually to already imported
images, define a shortcut (lua shortcuts). As I couldn't find an event for
when a development is removed, so the autostyle won't be applied again,
this shortcut is also helpful then
* import your images, or use the shortcut on your already imported images
* To determine which tag you want, list all tags with exiftool:
exiftool -j XE021351.RAF, and find the one you want to use
you can check it with
> exiftool -AutoDynamicRange XE021351.RAF
Auto Dynamic Range : 200%
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
* exiftool
LICENSE
GPLv2
]]
local darktable = require "darktable"
local du = require "lib/dtutils"
local filelib = require "lib/dtutils.file"
local syslib = require "lib/dtutils.system"
du.check_min_api_version("7.0.0", "autostyle")
local gettext = darktable.gettext.gettext
local function _(msgid)
return gettext(msgid)
end
-- return data structure for script_manager
local script_data = {}
local have_not_printed_config_message = true
script_data.metadata = {
name = _("auto style"),
purpose = _("automatically apply a style based on image EXIF tag"),
author = "Marc Cousin <cousinmarc@gmail.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/autostyle/"
}
script_data.destroy = nil -- function to destory the script
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
script_data.show = nil -- only required for libs since the destroy_method only hides them
-- run command and retrieve stdout
local function get_stdout(cmd)
-- Open the command, for reading
local fd = assert(io.popen(cmd, 'r'))
darktable.control.read(fd)
-- slurp the whole file
local data = assert(fd:read('*a'))
fd:close()
-- Replace carriage returns and linefeeds with spaces
data = string.gsub(data, '[\n\r]+', ' ')
-- Remove spaces at the beginning
data = string.gsub(data, '^%s+', '')
-- Remove spaces at the end
data = string.gsub(data, '%s+$', '')
return data
end
-- Retrieve the attribute through exiftool
local function exiftool_attribute(path, attr)
local cmd = "exiftool -" .. attr .. " '" .. path .. "'";
local exifresult = get_stdout(cmd)
local attribute = string.match(exifresult, ": (.*)")
if (attribute == nil) then
darktable.print_error( "Could not find the attribute " .. attr .. " using the command: <" .. cmd .. ">")
-- Raise an error to the caller
error( "Could not find the attribute " .. attr .. " using the command: <" .. cmd .. ">");
end
-- darktable.print_error("Returning attribute: " .. attribute)
return attribute
end
-- Apply the style to an image, if it matches the tag condition
local function autostyle_apply_one_image (image)
local pref = darktable.preferences.read("autostyle", "exif_tag", "string")
if pref and string.len(pref) >= 6 then
-- We need the tag, the value and the style_name provided from the configuration string
local tag, value, style_name = string.match(pref, "(%g+)%s*=%s*(%g+)%s*=>%s*(%g+)")
-- check they all exist (correct syntax)
if (not tag) then
darktable.print(string.format(_("EXIF tag not found in %s"), pref))
return 0
end
if (not value) then
darktable.print(string.format(_("value to match not found in %s"), pref))
return 0
end
if (not style_name) then
darktable.print(string.format(_("style name not found in %s"), pref))
return 0
end
if not filelib.check_if_bin_exists("exiftool") then
darktable.print(_("can't find exiftool"))
return 0
end
-- First find the style (we have its name)
local styles = darktable.styles
local style
for _, s in ipairs(styles) do
if s.name == style_name then
style = s
end
end
if (not style) then
darktable.print(string.format(_("style not found for autostyle: %s"), style_name))
return 0
end
-- Apply the style to image, if it is tagged
local ok, auto_dr_attr = pcall(exiftool_attribute, image.path .. '/' .. image.filename,tag)
--darktable.print_error("dr_attr:" .. auto_dr_attr)
-- If the lookup fails, stop here
if (not ok) then
darktable.print(string.format(_("couldn't get attribute %s from exiftool's output"), auto_dr_attr))
return 0
end
if auto_dr_attr == value then
darktable.print_log("Image " .. image.filename .. ": autostyle automatically applied " .. pref)
darktable.styles.apply(style,image)
return 1
else
darktable.print_log("Image " .. image.filename .. ": autostyle not applied, exif tag " .. pref .. " not matched: " .. auto_dr_attr)
return 0
end
elseif have_not_printed_config_message then
have_not_printed_config_message = false
darktable.print(string.format(_("%s is not configured, please configure the preference in Lua options"), script_data.metadata.name))
end
end
-- Receive the event triggered
local function autostyle_apply_one_image_event(event,image)
autostyle_apply_one_image(image)
end
local function autostyle_apply(shortcut)
local images = darktable.gui.action_images
local images_processed = 0
local images_submitted = 0
for _,image in pairs(images) do
images_submitted = images_submitted + 1
images_processed = images_processed + autostyle_apply_one_image(image)
end
darktable.print(string.format(_("applied auto style to %d out of %d image(s)"), images_processed, images_submitted))
end
local function destroy()
darktable.destroy_event("autostyle", "shortcut")
darktable.destroy_event("autostyle", "post-import-image")
end
-- Registering events
darktable.register_event("autostyle", "shortcut", autostyle_apply,
_("apply your chosen style from exiftool tags"))
darktable.preferences.register("autostyle", "exif_tag", "string",
string.format("%s: EXIF_tag=value=>style", script_data.metadata.name),
_("apply a style automatically if an EXIF tag matches value, find the tag with exiftool"), "")
darktable.register_event("autostyle", "post-import-image",
autostyle_apply_one_image_event)
script_data.destroy = destroy
return script_data