@@ -34,10 +34,13 @@ Additional tags or style can be applied on auto import as well, if you desire.
3434Base Options:
3535Select your desired BPS (bits per sample and Embedded Preview Size.
3636
37- Batch Options:
37+ Batch Mode Options:
3838Select if you want to run in batch mode or not
3939Select the gap, in seconds, between images for auto grouping in batch mode
4040
41+ Group Mode Options:
42+ The HDR image will be placed back in its group. Select if you want it to become the group leader.
43+
4144See HDRMerge manual for further detail: http://jcelaya.github.io/hdrmerge/documentation/2014/07/11/user-manual.html
4245
4346Auto-import Options:
@@ -208,61 +211,55 @@ end
208211local function UpdateActivePreference () -- sliders & entry boxes do not have a click/changed callback, so their values must be saved to the active preference
209212 temp = GUI .HDR .gap .value
210213 dt .preferences .write (mod , ' active_gap' , ' integer' , temp )
214+ temp = GUI .HDR .make_group_leader .value
215+ dt .preferences .write (mod , ' active_make_group_leader' , ' bool' , temp )
211216 temp = GUI .Target .add_tags .text
212217 dt .preferences .write (mod , ' active_add_tags' , ' string' , temp )
213218end
214219
215- local function main ()
216- PreCall ({HDRM }) -- check if furst run then check if install OK
217- if HDRM .install_error then
218- dt .print_error (' HDRMerge install issue' )
219- dt .print (_ (' HDRMerge install issue, please ensure the binary path is correct' ))
220- return
221- end
222- images = dt .gui .action_images -- get selected images
223- if # images < 2 then -- ensure enough images selected
224- dt .print (_ (' not enough images selected, select at least 2 images to merge' ))
225- return
226- end
227-
228- UpdateActivePreference () -- save current gui elements to active preference so those values will be pre-loaded at next startup
229-
230- -- create image string and output path
231- HDRM .images_string = ' '
220+ local function DoBatch (prog_table , images , output_arg )
221+ local prog = {}
222+ -- Copy program arguments
223+ for k , v in pairs (prog_table ) do prog [k ] = v end
232224 local out_path = ' '
233225 local smallest_id = math.huge
234226 local smallest_name = ' '
235227 local largest_id = 0
236228 local source_raw = {}
237- for _ ,image in pairs (images ) do -- loop to concat the images string, also track the image indexes for use in creating the final image name (eg; IMG_1034-1037.dng)
238- local curr_image = image .path .. os_path_seperator .. image .filename
239- HDRM .images_string = HDRM .images_string .. df .sanitize_filename (curr_image ).. ' '
240- out_path = image .path
241- _unused , source_name , source_id = GetFileName (image .filename )
242- source_id = tonumber (source_id ) or 0
243- if source_id < smallest_id then
244- smallest_id = source_id
245- smallest_name = source_name
246- source_raw = image
229+ local image_files = {}
230+ for _ ,image in ipairs (images ) do -- loop to concat the images string, also track the image indexes for use in creating the final image name (eg; IMG_1034-1037.dng)
231+ if not image .is_hdr then
232+ num_images = num_images + 1
233+ local curr_image = image .path .. os_path_seperator .. image .filename
234+ table.insert (image_files , df .sanitize_filename (curr_image ))
235+ _unused , source_name , source_id = GetFileName (image .filename )
236+ source_id = tonumber (source_id ) or 0
237+ if source_id < smallest_id then
238+ out_path = image .path
239+ smallest_id = source_id
240+ smallest_name = source_name
241+ source_raw = image
242+ end
243+ if source_id > largest_id then largest_id = source_id end
247244 end
248- if source_id > largest_id then largest_id = source_id end
249245 end
250- out_path = out_path .. os_path_seperator .. smallest_name .. ' - ' .. largest_id .. ' .dng '
251- out_path = df . create_unique_filename ( out_path )
252-
253- -- create argument string
254- HDRM . arg_string = HDRM . args . bps . text .. GUI . HDR . bps . value .. ' ' .. HDRM . args . size . text .. GUI . HDR . size . value .. ' '
255- if GUI . HDR . batch . value then
256- HDRM . arg_string = HDRM . arg_string .. HDRM . args . batch . text .. HDRM . args . gap . text .. math.floor ( GUI . HDR . gap . value ) .. ' -a '
257- else
258- HDRM .arg_string = HDRM .arg_string .. ' -o ' .. df .sanitize_filename (out_path )
246+ if # image_files < 2 then
247+ dt . print ( _ ( " not enough images in group, skipping " ) )
248+ return
249+ end
250+ prog . images_string = table.concat ( image_files , ' ' )
251+ if output_arg then
252+ out_path = out_path .. os_path_seperator .. smallest_name .. ' - ' .. largest_id .. ' .dng '
253+ out_path = df . create_unique_filename ( out_path )
254+ prog .arg_string = prog .arg_string .. ' -o ' .. df .sanitize_filename (out_path )
259255 end
260256
261257 -- create run command and execute
262- local run_cmd = BuildExecuteCmd (HDRM )
258+ local run_cmd = BuildExecuteCmd (prog )
259+ dt .print_log (' running HDRMerge: ' .. run_cmd )
263260 resp = dsys .external_command (run_cmd )
264261
265- if resp == 0 and not GUI . HDR . batch . value then
262+ if resp == 0 and output_arg then
266263 local imported = dt .database .import (out_path ) -- import the new file
267264 if GUI .Target .style .selected > 1 then -- apply selected style
268265 local set_style = styles [GUI .Target .style .selected - 1 ]
@@ -283,11 +280,65 @@ local function main()
283280 end
284281 end
285282 dt .print (_ (' HDRMerge completed successfully' ))
286- else
283+ return imported
284+ elseif resp == 0 then
285+ dt .print (_ (' HDRMerge completed successfully' ))
286+ return nil -- TODO: can detect created files?
287+ elseif resp ~= 0 then
287288 dt .print_error (' HDRMerge failed' )
288289 dt .print (_ (' HDRMerge failed' ))
289290 end
291+ end
290292
293+ local function main ()
294+ PreCall ({HDRM }) -- check if furst run then check if install OK
295+ if HDRM .install_error then
296+ dt .print_error (' HDRMerge install issue' )
297+ dt .print (_ (' HDRMerge install issue, please ensure the binary path is correct' ))
298+ return
299+ end
300+ images = dt .gui .action_images -- get selected images
301+ if # images < 2 then -- ensure enough images selected
302+ dt .print (_ (' not enough images selected, select at least 2 images to merge' ))
303+ return
304+ end
305+
306+ UpdateActivePreference () -- save current gui elements to active preference so those values will be pre-loaded at next startup
307+
308+ -- create argument string
309+ HDRM .arg_string = HDRM .args .bps .text .. GUI .HDR .bps .value .. ' ' .. HDRM .args .size .text .. GUI .HDR .size .value .. ' '
310+ if GUI .HDR .mode .selected == 2 then
311+ end
312+
313+ -- do mode operation
314+ if GUI .HDR .mode .selected == 1 then
315+ doBatch (HDRM , images , true )
316+ elseif GUI .HDR .mode .selected == 2 then
317+ HDRM .arg_string = HDRM .arg_string .. HDRM .args .batch .text .. HDRM .args .gap .text .. math.floor (GUI .HDR .gap .value ).. ' -a'
318+ dBatch (HDRM , images , false )
319+ elseif GUI .HDR .mode .selected == 3 then
320+ local by_group = {}
321+ for _ , im in ipairs (images ) do
322+ local leader = im .group_leader
323+ if not by_group [leader ] then by_group [leader ] = {} end
324+ table.insert (by_group [leader ], im )
325+ end
326+ for leader , group in pairs (by_group ) do
327+ local imported = DoBatch (HDRM , group , true )
328+ if imported then
329+ imported :group_with (leader )
330+
331+ if GUI .HDR .make_group_leader .value then
332+ imported :make_group_leader ()
333+ end
334+ end
335+ if dt .gui .libs .global_toolbox .grouping then
336+ -- Toggle off & on to update the view
337+ dt .gui .libs .global_toolbox .grouping = false
338+ dt .gui .libs .global_toolbox .grouping = true
339+ end
340+ end
341+ end
291342end
292343
293344local function install_module ()
@@ -353,21 +404,12 @@ GUI.HDR.size = dt.new_widget('combobox'){
353404 dt .preferences .write (mod , ' active_size_ind' , ' integer' , self .selected )
354405 end
355406}
356- GUI .HDR .batch = dt .new_widget (' check_button' ){
357- label = _ (' batch mode' ),
358- value = dt .preferences .read (mod , ' active_batch' , ' bool' ),
359- tooltip = _ (' enable batch mode operation \n NOTE: resultant files will NOT be auto-imported' ),
360- clicked_callback = function (self )
361- dt .preferences .write (mod , ' active_batch' , ' bool' , self .value )
362- GUI .HDR .gap .sensitive = self .value
363- end ,
364- reset_callback = function (self ) self .value = false end
365- }
407+
366408temp = dt .preferences .read (mod , ' active_gap' , ' integer' )
367409if not InRange (temp , 1 , 3600 ) then temp = 3 end
368410GUI .HDR .gap = dt .new_widget (' slider' ){
369411 label = _ (' batch gap [sec.]' ),
370- tooltip = _ (' gap, in seconds, between batch mode groups ' ),
412+ tooltip = _ (' gap, in seconds, between batch mode images within group ' ),
371413 soft_min = 1 ,
372414 soft_max = 30 ,
373415 hard_min = 1 ,
@@ -380,6 +422,44 @@ GUI.HDR.gap = dt.new_widget('slider'){
380422 self .value = 3
381423 end
382424}
425+
426+ GUI .HDR .make_group_leader = dt .new_widget (' check_button' ){
427+ label = _ (' make group leader' ),
428+ tooltip = _ (' make new image the group leader' ),
429+ value = dt .preferences .read (mod , ' active_make_group_leader' , ' bool' )
430+ }
431+ temp = dt .preferences .read (mod , ' active_mode' , ' integer' )
432+ if not InRange (temp , 1 , 3 ) then
433+ if dt .preferences .read (mod , ' active_batch' , ' bool' ) then
434+ temp = 2
435+ else
436+ temp = 1
437+ end
438+ end
439+ GUI .HDR .opts = dt .new_widget (' stack' ){
440+ dt .new_widget (' box' ),
441+ GUI .HDR .gap ,
442+ GUI .HDR .make_group_leader ,
443+ active = temp
444+ }
445+ GUI .HDR .mode = dt .new_widget (' combobox' ){
446+ label = _ (' mode' ),
447+ tooltip = _ ([[ Operating mode:
448+ all: merge all images into a single image
449+ batch: group images into sets by comparing creation time. Images will NOT be auto-imported
450+ groups: merge images according to image grouping]] ),
451+ value = temp ,
452+ changed_callback = function (self )
453+ dt .preferences .write (mod , ' active_mode' , ' integer' , self .selected )
454+ GUI .HDR .opts .active = self .selected
455+ end ,
456+ reset_callback = function (self ) self .selected = 1 end ,
457+ _ (' all' ),
458+ _ (' batch' ),
459+ _ (' groups' )
460+ }
461+
462+
383463local lbl_import = dt .new_widget (' section_label' ){
384464 label = _ (' import options' )
385465}
@@ -439,8 +519,8 @@ GUI.options = dt.new_widget('box'){
439519 lbl_hdr ,
440520 GUI .HDR .bps ,
441521 GUI .HDR .size ,
442- GUI .HDR .batch ,
443- GUI .HDR .gap ,
522+ GUI .HDR .mode ,
523+ GUI .HDR .opts ,
444524 lbl_import ,
445525 GUI .Target .style ,
446526 GUI .Target .copy_tags ,
0 commit comments