Skip to content

Commit 3d14c0a

Browse files
committed
gimp_stack.lua - hacking.
- added align_image_stack to the pipeline - apply source image ratings and metadata to resulting tiff - store output tiff beside source images (so that gimp xcf is also easily placed there when (optionally) saving.
1 parent 3f0e0ea commit 3d14c0a

File tree

1 file changed

+111
-24
lines changed

1 file changed

+111
-24
lines changed

contrib/gimp_stack.lua

Lines changed: 111 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@
6363
]]
6464

6565
local dt = require "darktable"
66-
local dtutils = require "contrib/dtutils"
66+
local dtutils = require "lib/dtutils"
6767
local gettext = dt.gettext
68+
require "official/yield"
6869

69-
dt.configuration.check_version(...,{3,0,0})
70+
-- FIXME: do we really need this? dt.configuration.check_version(...,{3,0,0})
7071

7172
-- Tell gettext where to find the .mo file translating messages for a particular domain
7273
gettext.bindtextdomain("gimp_stack",dt.configuration.config_dir.."/lua/")
@@ -81,54 +82,140 @@ local function show_status(storage, image, format, filename,
8182
dt.print(string.format(_("Exporting to gimp %i/%i"), number, total))
8283
end
8384

84-
local function gimp_stack_edit(storage, image_table, extra_data) --finalize
85-
if not dtutils.checkIfBinExists("gimp") then
86-
dt.print_error(_("gimp not found"))
87-
return
88-
end
85+
-- ==== from image_stack ======
86+
-- copy an images database attributes to another image. This only
87+
-- copies what the database knows, not the actual exif data in the
88+
-- image itself.
8989

90-
if not dtutils.checkIfBinExists("convert") then
91-
dt.print_error(_("convert not found"))
92-
return
90+
local function copy_image_attributes(from, to, ...)
91+
local args = {...}
92+
if #args == 0 then
93+
args[1] = "all"
94+
end
95+
if args[1] == "all" then
96+
args[1] = "rating"
97+
args[2] = "colors"
98+
args[3] = "exif"
99+
args[4] = "meta"
100+
args[5] = "GPS"
93101
end
102+
for _,arg in ipairs(args) do
103+
if arg == "rating" then
104+
to.rating = from.rating
105+
elseif arg == "colors" then
106+
to.red = from.red
107+
to.blue = from.blue
108+
to.green = from.green
109+
to.yellow = from.yellow
110+
to.purple = from.purple
111+
elseif arg == "exif" then
112+
to.exif_maker = from.exif_maker
113+
to.exif_model = from.exif_model
114+
to.exif_lens = from.exif_lens
115+
to.exif_aperture = from.exif_aperture
116+
to.exif_exposure = from.exif_exposure
117+
to.exif_focal_length = from.exif_focal_length
118+
to.exif_iso = from.exif_iso
119+
to.exif_datetime_taken = from.exif_datetime_taken
120+
to.exif_focus_distance = from.exif_focus_distance
121+
to.exif_crop = from.exif_crop
122+
elseif arg == "GPS" then
123+
to.elevation = from.elevation
124+
to.longitude = from.longitude
125+
to.latitude = from.latitude
126+
elseif arg == "meta" then
127+
to.publisher = from.publisher
128+
to.title = from.title
129+
to.creator = from.creator
130+
to.rights = from.rights
131+
to.description = from.description
132+
else
133+
dt.print_error(_("Unrecognized option to copy_image_attributes: " .. arg))
134+
end
135+
end
136+
end
137+
138+
-- == end of copy_image_attributes from image_stack.lua
139+
140+
local function gimp_stack_edit(storage, image_table, extra_data) --finalize
141+
--if not dtutils.check_if_bin_exists("gimp") then
142+
-- dt.print_error(_("gimp not found"))
143+
-- return
144+
--end
145+
146+
--if not dtutils.check_if_bin_exists("convert") then
147+
-- dt.print_error(_("convert not found"))
148+
-- return
149+
--end
94150

95151
-- list of exported images
96152
local img_list
153+
local align_list
97154

98155
-- reset and create image list
99156
img_list = ""
157+
align_list = ""
100158

101159
for _,exp_img in pairs(image_table) do
160+
-- exp_img = '/tmp/IMG_9519.tif'
102161
img_list = img_list ..exp_img.. " "
103162
end
104163
dt.print_error(img_list)
105164

106-
local tmp_stack_image = dt.configuration.tmp_dir.."/stack.tif"
107165

108-
dt.print(_("Stacking images..."))
166+
-- Instead of working on a stacked tiff in tmp, we put in
167+
-- with the source images so that gimp can also easily save
168+
-- an xcf (ignored by dt) in the same directory without having
169+
-- to hunt around for the right folder.
170+
--
171+
-- local tmp_stack_image = dt.configuration.tmp_dir.."/stack.tif"
109172

110-
os.execute("convert "..img_list.." "..tmp_stack_image)
173+
-- FIXME: low-priority. Should check for existing destination file, and make a sensible
174+
-- choice rather than blindly over-writing like this.
175+
local stack_image = dt.gui.action_images[1].path .. "/" .. dt.gui.action_images[1].filename ..".gimp_stack.tif"
176+
-- FIXME: low-priority, but we should be careful to get an actual temp name for
177+
-- the prefix to avoid clobbering or including ones we didn't expect to be there.
178+
local align_prefix = dt.configuration.tmp_dir.."/"..dt.gui.action_images[1].filename ..".aligned-"
179+
180+
dt.print(_("Aligning images..."))
181+
182+
os.execute("align_image_stack -a " .. align_prefix .. " -m -d -i --distortion --gpu "..img_list)
183+
184+
185+
dt.print(_("Stacking images into "..align_prefix.."* ..."))
186+
187+
188+
189+
os.execute("convert "..align_prefix.."* "..stack_image)
111190
os.execute("rm "..img_list)
191+
os.execute("rm "..align_prefix.."*")
112192

113193
dt.print(_("Launching gimp..."))
114194

115195
local gimpStartCommand
116-
gimpStartCommand = "gimp "..tmp_stack_image
196+
gimpStartCommand = "gimp "..stack_image
117197

118198
dt.print_error(gimpStartCommand)
119199

120-
coroutine.yield("RUN_COMMAND", gimpStartCommand)
200+
-- coroutine.yield("RUN_COMMAND", gimpStartCommand)
201+
-- AJG - probably need to use dtsys.external_command() or something here, I am guessing.
202+
os.execute(gimpStartCommand)
203+
204+
-- AJG seems sensible to wait until after we finish editing before importing. Probably
205+
-- OK either way, but we might avoid some thumbnail / metadata weirdnesses.
206+
207+
dt.print(_("Importing image and copying tags..."))
208+
local imported_image = dt.database.import(stack_image)
209+
local created_tag = dt.tags.create(_("Created with|gimp_stack|sources ".. img_list ..""))
210+
dt.tags.attach(created_tag, imported_image)
211+
-- all the images are the same except for time, so just copy the attributes
212+
-- from the first
213+
for img,_ in pairs(image_table) do
214+
copy_image_attributes(img, imported_image)
215+
break
216+
end
121217

122-
-- for each of the exported images
123-
-- find the matching original image
124-
-- then move the exported image into the directory with the original
125-
-- then import the image into the database which will group it with the original
126-
-- and then copy over any tags other than darktable tags
127218

128-
local collection_path = dt.gui.action_images[1].path
129-
local final_stack_image = collection_path.."/stack.tif"
130-
os.execute("mv "..tmp_stack_image.." "..final_stack_image)
131-
local myimage = dt.database.import(final_stack_image)
132219

133220
end
134221

0 commit comments

Comments
 (0)