Skip to content

Commit fdc484e

Browse files
committed
Merge pull request darktable-org#1 from darktable-org/master
Merge with master
2 parents 74a241a + 8aab42e commit fdc484e

10 files changed

+683
-33
lines changed

contrib/autostyle.lua

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
--[[
2+
Autostyle
3+
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.
4+
I wrote this initially to be able to apply a style to compensate for Auto-DR from my Fujifilm camera
5+
6+
AUTHOR
7+
Marc Cousin ([email protected])
8+
9+
INSTALATION
10+
* copy this file in $CONFIGDIR/lua/ where CONFIGDIR
11+
is your darktable configuration directory
12+
* add the following line in the file $CONFIGDIR/luarc
13+
require "autostyle"
14+
15+
USAGE
16+
* set the exif configuration string in your lua configuration
17+
mine, for instance, is AutoDynamicRange=200%=>DR200"
18+
meaning that I automatically want to apply my DR200 style on all
19+
images where exiftool returns '200%' for the AutoDynamicRange tag
20+
* if you want to be able to apply it manually to already imported
21+
images, define a shortcut (lua shortcuts). As I couldn't find an event for
22+
when a development is removed, so the autostyle won't be applied again,
23+
this shortcut is also helpful then
24+
* import your images, or use the shortcut on your already imported images
25+
* To determine which tag you want, list all tags with exiftool:
26+
exiftool -j XE021351.RAF, and find the one you want to use
27+
you can check it with
28+
> exiftool -AutoDynamicRange XE021351.RAF
29+
Auto Dynamic Range : 200%
30+
31+
32+
LICENSE
33+
GPLv2
34+
35+
]]
36+
37+
local darktable = require "darktable"
38+
39+
40+
-- Forward declare the functions
41+
local autostyle_apply_one_image,autostyle_apply_one_image_event,autostyle_apply,exiftool_attribute,capture
42+
43+
-- Tested it with darktable 1.6.1 and darktable git from 2014-01-25
44+
darktable.configuration.check_version(...,{2,0,2},{2,1,0})
45+
46+
-- Receive the event triggered
47+
function autostyle_apply_one_image_event(event,image)
48+
autostyle_apply_one_image(image)
49+
end
50+
51+
-- Apply the style to an image, if it matches the tag condition
52+
function autostyle_apply_one_image (image)
53+
-- We need the tag, the value and the style_name provided from the configuration string
54+
local tag,value,style_name=string.match(darktable.preferences.read("autostyle","exif_tag","string"),"(%g+)%s*=%s*(%g+)%s*=>%s*(%g+)")
55+
56+
-- check they all exist (correct syntax)
57+
if (not tag) then
58+
darktable.print("EXIF TAG not found in " .. darktable.preferences.read("autostyle","exif_tag","string"))
59+
return
60+
end
61+
if (not value) then
62+
darktable.print("value to match not found in " .. darktable.preferences.read("autostyle","exif_tag","string"))
63+
return
64+
end
65+
if (not style_name) then
66+
darktable.print("style name not found in " .. darktable.preferences.read("autostyle","exif_tag","string"))
67+
return
68+
end
69+
70+
-- First find the style (we have its name)
71+
local styles= darktable.styles
72+
local style
73+
for _,s in ipairs(styles) do
74+
if s.name == style_name then
75+
style=s
76+
end
77+
end
78+
if (not style) then
79+
darktable.print("style not found for autostyle: " .. style_name)
80+
end
81+
82+
-- Apply the style to image, if it is tagged
83+
local ok,auto_dr_attr= pcall(exiftool_attribute,image.path .. '/' .. image.filename,tag)
84+
-- If the lookup fails, stop here
85+
if (not ok) then
86+
return
87+
end
88+
if auto_dr_attr==value then
89+
-- darktable.print("Image " .. image.filename .. ": autostyle automatically applied " .. darktable.preferences.read("autostyle","exif_tag","string") )
90+
darktable.styles.apply(style,image)
91+
-- else
92+
-- darktable.print("Image " .. image.filename .. ": autostyle not applied, exif tag " .. darktable.preferences.read("autostyle","exif_tag","string") .. " not matched: " .. auto_dr_attr)
93+
end
94+
end
95+
96+
97+
function autostyle_apply( shortcut)
98+
local images = darktable.gui.action_images
99+
for _,image in pairs(images) do
100+
autostyle_apply_one_image(image)
101+
end
102+
end
103+
104+
-- Retrieve the attribute through exiftool
105+
function exiftool_attribute(path,attr)
106+
local cmd="exiftool -" .. attr .. " '" ..path.. "'";
107+
local exifresult=get_stdout(cmd)
108+
local attribute=string.match(exifresult,": (.*)")
109+
if (attribute == nil) then
110+
darktable.print( "Could not find the attribute " .. attr .. " using the command: <" .. cmd .. ">")
111+
-- Raise an error to the caller
112+
error( "Could not find the attribute " .. attr .. " using the command: <" .. cmd .. ">");
113+
end
114+
return attribute
115+
end
116+
117+
-- run command and retrieve stdout
118+
function get_stdout(cmd)
119+
-- Open the command, for reading
120+
local fd = assert(io.popen(cmd, 'r'))
121+
-- yield to other lua threads until data is ready to be read
122+
coroutine.yield("FILE_READABLE",fd)
123+
-- slurp the whole file
124+
local data = assert(fd:read('*a'))
125+
126+
fd:close()
127+
-- Replace carriage returns and linefeeds with spaces
128+
data = string.gsub(data, '[\n\r]+', ' ')
129+
-- Remove spaces at the beginning
130+
data = string.gsub(data, '^%s+', '')
131+
-- Remove spaces at the end
132+
data = string.gsub(data, '%s+$', '')
133+
return data
134+
end
135+
136+
-- Registering events
137+
darktable.register_event("shortcut",autostyle_apply,
138+
"Apply your chosen style from exiftool tags")
139+
140+
darktable.preferences.register("autostyle","exif_tag","string","Autostyle: EXIF_tag=value=>style","apply a style automatically if an EXIF_tag matches value. Find the tag with exiftool","")
141+
142+
darktable.register_event("post-import-image",autostyle_apply_one_image_event)
143+
144+

contrib/copy_attach_detach_tags.lua

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
--[[
2-
copyright (c) 2014 Christian Kanzian
3-
LICENSE GPLv2
4-
]]
2+
This file is part of darktable,
3+
copyright 2014-2015 by Christian Kanzian.
4+
5+
This program is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU General Public License as published by
7+
the Free Software Foundation; either version 3 of the License, or
8+
(at your option) any later version.
9+
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU General Public License for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
]]
518

619
--[[
7-
(MULTI-)COPY ATTACH DETACH TAG
8-
A simple script that will create three shortcuts to copy, attach and detach image tags.
20+
(MULTI-)COPY ATTACH DETACH TAG
21+
A simple script that will create three shortcuts to copy, attach and detach image tags.
922
1023
INSTALATION
11-
* copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory
12-
* add the following line in the file $CONFIGDIR/luarc require "copy_attach_detach_tags.lua"
24+
* copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory
25+
* add the following line in the file $CONFIGDIR/luarc require "copy_attach_detach_tags"
1326
1427
USAGE
15-
* set the shortcuts for copy, attach and detach in the preferences dialog
16-
* <your shortcut1> copy will create a list of tags from all selected images
17-
* <your shortcut2> attaches copied tags to selected images, whereby
18-
darktable internal tags starting with 'darktable|' will not be touched
19-
* <your shortcut3> detach removes all expect darktable internal tags from selected images
28+
* set the shortcuts for copy, attach and detach in the preferences dialog
29+
* <your shortcut1> copy will create a list of tags from all selected images
30+
* <your shortcut2> attaches copied tags to selected images, whereby
31+
darktable internal tags starting with 'darktable|' will not be touched
32+
* <your shortcut3> detach removes all expect darktable internal tags from selected images
2033
2134
]]
2235

@@ -26,10 +39,12 @@ dt.configuration.check_version(...,{2,0,0})
2639
local image_tags = {}
2740

2841
local function mcopy_tags()
29-
local sel_images = dt.gui.selection()
30-
local tag_list_tmp = {}
31-
local hash = {}
42+
local sel_images = dt.gui.action_images
43+
local tag_list_tmp = {}
44+
local hash = {}
3245

46+
-- empty tag table before copy new tags
47+
image_tags = {}
3348
for _,image in ipairs(sel_images) do
3449
local image_tags_tmp = {}
3550
image_tags_tmp = dt.tags.get_tags(image)
@@ -50,18 +65,18 @@ local hash = {}
5065
end
5166
end
5267

53-
-- dt.print("Tags copied.")
68+
dt.print("Image tags copied ...")
5469
return(image_tags)
5570
end
5671

5772
-- attach copied tags to all selected images
5873
local function attach_tags()
5974

6075
if next(image_tags) == nil then
61-
dt.print("No tags copied, please copy tags first.")
76+
dt.print("No tags to attached, please copy tags first.")
6277
end
6378

64-
local sel_images = dt.gui.selection()
79+
local sel_images = dt.gui.action_images
6580

6681
for _,image in ipairs(sel_images) do
6782
local present_image_tags = {}
@@ -81,13 +96,14 @@ local function attach_tags()
8196
end
8297
end
8398
end
99+
dt.print("Tags attached ...")
84100
end
85101

86102

87103

88104

89105
local function detach_tags()
90-
local sel_images = dt.gui.selection()
106+
local sel_images = dt.gui.action_images
91107

92108
for _,image in ipairs(sel_images) do
93109
local present_image_tags = {}
@@ -99,7 +115,8 @@ local function detach_tags()
99115
end
100116
end
101117
end
102-
end
118+
dt.print("Tags removed from image(s).")
119+
end
103120

104121
-- shortcut for copy
105122
dt.register_event("shortcut",
@@ -118,4 +135,4 @@ dt.register_event("shortcut",
118135

119136

120137
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
121-
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
138+
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;

contrib/cr2hdr.lua

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
--[[
2+
Copyright (C) 2015 Till Theato <[email protected]>.
3+
4+
This program is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation; either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
This program is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
]]
17+
--[[
18+
cr2hdr Magic Lantern Dual ISO processing.
19+
20+
This script automates the steps involved to process an image created
21+
with the Magic Lantern Dual ISO module. Upon invoking the script with a
22+
shortcut "cr2hdr" provided by Magic Lantern is run on the selected
23+
images. The processed files are imported. They are also made group
24+
leaders to hide the original files.
25+
26+
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
27+
* cr2hdr (sources can be obtained through the Magic Lantern repository)
28+
29+
USAGE
30+
* require this script from your main lua file
31+
* trigger conversion on selected/hovered images by shortcut (set shortcut in settings dialog)
32+
* it is also possible to have the script run after importing a collection (optin, since it is not that fast)
33+
]]
34+
35+
local darktable = require "darktable"
36+
37+
-- Tested with darktable 1.6.2
38+
darktable.configuration.check_version(...,{2,0,2})
39+
40+
local queue = {}
41+
local processed_files = {}
42+
local job
43+
44+
local function file_imported(event, image)
45+
local filename = image.path .. "/" .. image.filename
46+
if processed_files[filename] then
47+
image.make_group_leader(image)
48+
processed_files[filename] = false
49+
else
50+
if darktable.preferences.read("cr2hdr", "onimport", "bool") then
51+
table.insert(queue, image)
52+
end
53+
end
54+
end
55+
56+
local function stop_conversion(job)
57+
job.valid = false
58+
end
59+
60+
local function convert_image(image)
61+
if string.sub(image.filename, -3) == "CR2" then
62+
local filename = image.path .. "/" .. image.filename
63+
local result = coroutine.yield("RUN_COMMAND", "cr2hdr " .. filename)
64+
local out_filename = string.gsub(filename, ".CR2", ".DNG")
65+
local file = io.open(out_filename)
66+
if file then
67+
file:close()
68+
processed_files[out_filename] = true
69+
darktable.database.import(out_filename)
70+
else
71+
darktable.print_error(filename .. ": cr2hdr failed.")
72+
end
73+
else
74+
darktable.print_error(image.filename .. " is not a Canon RAW.")
75+
end
76+
end
77+
78+
local function convert_images()
79+
if next(queue) == nil then return end
80+
81+
job = darktable.gui.create_job("Dual ISO conversion", true, stop_conversion)
82+
for key,image in pairs(queue) do
83+
if job.valid then
84+
job.percent = (key-1)/#queue
85+
convert_image(image)
86+
else
87+
break
88+
end
89+
end
90+
local success_count = 0
91+
for _ in pairs(processed_files) do success_count = success_count + 1 end
92+
darktable.print("Dual ISO conversion successful on " .. success_count .. "/" .. #queue .. " images.")
93+
job.valid = false
94+
processed_files = {}
95+
queue = {}
96+
end
97+
98+
local function film_imported(event, film)
99+
if darktable.preferences.read("cr2hdr", "onimport", "bool") then
100+
convert_images()
101+
end
102+
end
103+
104+
local function convert_action_images(shortcut)
105+
queue = darktable.gui.action_images
106+
convert_images()
107+
end
108+
109+
darktable.register_event("shortcut", convert_action_images, "Run cr2hdr (Magic Lantern DualISO converter) on selected images")
110+
darktable.register_event("post-import-image", file_imported)
111+
darktable.register_event("post-import-film", film_imported)
112+
113+
darktable.preferences.register("cr2hdr", "onimport", "bool", "Invoke on import", "If true then cr2hdr will try to proccess every file during importing. Warning: cr2hdr is quite slow even in figuring out on whether the file is Dual ISO or not.", false)

0 commit comments

Comments
 (0)