144
contrib/autostyle.lua
Normal file
144
contrib/autostyle.lua
Normal file
@@ -0,0 +1,144 @@
|
||||
--[[
|
||||
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%
|
||||
|
||||
|
||||
LICENSE
|
||||
GPLv2
|
||||
|
||||
]]
|
||||
|
||||
local darktable = require "darktable"
|
||||
|
||||
|
||||
-- Forward declare the functions
|
||||
local autostyle_apply_one_image,autostyle_apply_one_image_event,autostyle_apply,exiftool_attribute,capture
|
||||
|
||||
-- Tested it with darktable 1.6.1 and darktable git from 2014-01-25
|
||||
darktable.configuration.check_version(...,{2,0,2},{2,1,0})
|
||||
|
||||
-- Receive the event triggered
|
||||
function autostyle_apply_one_image_event(event,image)
|
||||
autostyle_apply_one_image(image)
|
||||
end
|
||||
|
||||
-- Apply the style to an image, if it matches the tag condition
|
||||
function autostyle_apply_one_image (image)
|
||||
-- We need the tag, the value and the style_name provided from the configuration string
|
||||
local tag,value,style_name=string.match(darktable.preferences.read("autostyle","exif_tag","string"),"(%g+)%s*=%s*(%g+)%s*=>%s*(%g+)")
|
||||
|
||||
-- check they all exist (correct syntax)
|
||||
if (not tag) then
|
||||
darktable.print("EXIF TAG not found in " .. darktable.preferences.read("autostyle","exif_tag","string"))
|
||||
return
|
||||
end
|
||||
if (not value) then
|
||||
darktable.print("value to match not found in " .. darktable.preferences.read("autostyle","exif_tag","string"))
|
||||
return
|
||||
end
|
||||
if (not style_name) then
|
||||
darktable.print("style name not found in " .. darktable.preferences.read("autostyle","exif_tag","string"))
|
||||
return
|
||||
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("style not found for autostyle: " .. style_name)
|
||||
end
|
||||
|
||||
-- Apply the style to image, if it is tagged
|
||||
local ok,auto_dr_attr= pcall(exiftool_attribute,image.path .. '/' .. image.filename,tag)
|
||||
-- If the lookup fails, stop here
|
||||
if (not ok) then
|
||||
return
|
||||
end
|
||||
if auto_dr_attr==value then
|
||||
-- darktable.print("Image " .. image.filename .. ": autostyle automatically applied " .. darktable.preferences.read("autostyle","exif_tag","string") )
|
||||
darktable.styles.apply(style,image)
|
||||
-- else
|
||||
-- darktable.print("Image " .. image.filename .. ": autostyle not applied, exif tag " .. darktable.preferences.read("autostyle","exif_tag","string") .. " not matched: " .. auto_dr_attr)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function autostyle_apply( shortcut)
|
||||
local images = darktable.gui.action_images
|
||||
for _,image in pairs(images) do
|
||||
autostyle_apply_one_image(image)
|
||||
end
|
||||
end
|
||||
|
||||
-- Retrieve the attribute through exiftool
|
||||
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( "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
|
||||
return attribute
|
||||
end
|
||||
|
||||
-- run command and retrieve stdout
|
||||
function get_stdout(cmd)
|
||||
-- Open the command, for reading
|
||||
local fd = assert(io.popen(cmd, 'r'))
|
||||
-- yield to other lua threads until data is ready to be read
|
||||
coroutine.yield("FILE_READABLE",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
|
||||
|
||||
-- Registering events
|
||||
darktable.register_event("shortcut",autostyle_apply,
|
||||
"Apply your chosen style from exiftool tags")
|
||||
|
||||
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","")
|
||||
|
||||
darktable.register_event("post-import-image",autostyle_apply_one_image_event)
|
||||
|
||||
|
||||
@@ -1,22 +1,35 @@
|
||||
--[[
|
||||
copyright (c) 2014 Christian Kanzian
|
||||
LICENSE GPLv2
|
||||
]]
|
||||
This file is part of darktable,
|
||||
copyright 2014-2015 by Christian Kanzian.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
|
||||
--[[
|
||||
(MULTI-)COPY ATTACH DETACH TAG
|
||||
A simple script that will create three shortcuts to copy, attach and detach image tags.
|
||||
(MULTI-)COPY ATTACH DETACH TAG
|
||||
A simple script that will create three shortcuts to copy, attach and detach image tags.
|
||||
|
||||
INSTALATION
|
||||
* copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory
|
||||
* add the following line in the file $CONFIGDIR/luarc require "copy_attach_detach_tags.lua"
|
||||
* copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory
|
||||
* add the following line in the file $CONFIGDIR/luarc require "copy_attach_detach_tags"
|
||||
|
||||
USAGE
|
||||
* set the shortcuts for copy, attach and detach in the preferences dialog
|
||||
* <your shortcut1> copy will create a list of tags from all selected images
|
||||
* <your shortcut2> attaches copied tags to selected images, whereby
|
||||
darktable internal tags starting with 'darktable|' will not be touched
|
||||
* <your shortcut3> detach removes all expect darktable internal tags from selected images
|
||||
* set the shortcuts for copy, attach and detach in the preferences dialog
|
||||
* <your shortcut1> copy will create a list of tags from all selected images
|
||||
* <your shortcut2> attaches copied tags to selected images, whereby
|
||||
darktable internal tags starting with 'darktable|' will not be touched
|
||||
* <your shortcut3> detach removes all expect darktable internal tags from selected images
|
||||
|
||||
]]
|
||||
|
||||
@@ -26,10 +39,12 @@ dt.configuration.check_version(...,{2,0,0})
|
||||
local image_tags = {}
|
||||
|
||||
local function mcopy_tags()
|
||||
local sel_images = dt.gui.selection()
|
||||
local tag_list_tmp = {}
|
||||
local hash = {}
|
||||
local sel_images = dt.gui.action_images
|
||||
local tag_list_tmp = {}
|
||||
local hash = {}
|
||||
|
||||
-- empty tag table before copy new tags
|
||||
image_tags = {}
|
||||
for _,image in ipairs(sel_images) do
|
||||
local image_tags_tmp = {}
|
||||
image_tags_tmp = dt.tags.get_tags(image)
|
||||
@@ -50,7 +65,7 @@ local hash = {}
|
||||
end
|
||||
end
|
||||
|
||||
-- dt.print("Tags copied.")
|
||||
dt.print("Image tags copied ...")
|
||||
return(image_tags)
|
||||
end
|
||||
|
||||
@@ -58,10 +73,10 @@ local hash = {}
|
||||
local function attach_tags()
|
||||
|
||||
if next(image_tags) == nil then
|
||||
dt.print("No tags copied, please copy tags first.")
|
||||
dt.print("No tags to attached, please copy tags first.")
|
||||
end
|
||||
|
||||
local sel_images = dt.gui.selection()
|
||||
local sel_images = dt.gui.action_images
|
||||
|
||||
for _,image in ipairs(sel_images) do
|
||||
local present_image_tags = {}
|
||||
@@ -81,13 +96,14 @@ local function attach_tags()
|
||||
end
|
||||
end
|
||||
end
|
||||
dt.print("Tags attached ...")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
local function detach_tags()
|
||||
local sel_images = dt.gui.selection()
|
||||
local sel_images = dt.gui.action_images
|
||||
|
||||
for _,image in ipairs(sel_images) do
|
||||
local present_image_tags = {}
|
||||
@@ -99,7 +115,8 @@ local function detach_tags()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
dt.print("Tags removed from image(s).")
|
||||
end
|
||||
|
||||
-- shortcut for copy
|
||||
dt.register_event("shortcut",
|
||||
@@ -118,4 +135,4 @@ dt.register_event("shortcut",
|
||||
|
||||
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
|
||||
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
|
||||
|
||||
113
contrib/cr2hdr.lua
Normal file
113
contrib/cr2hdr.lua
Normal file
@@ -0,0 +1,113 @@
|
||||
--[[
|
||||
Copyright (C) 2015 Till Theato <theato@ttill.de>.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
cr2hdr Magic Lantern Dual ISO processing.
|
||||
|
||||
This script automates the steps involved to process an image created
|
||||
with the Magic Lantern Dual ISO module. Upon invoking the script with a
|
||||
shortcut "cr2hdr" provided by Magic Lantern is run on the selected
|
||||
images. The processed files are imported. They are also made group
|
||||
leaders to hide the original files.
|
||||
|
||||
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
|
||||
* cr2hdr (sources can be obtained through the Magic Lantern repository)
|
||||
|
||||
USAGE
|
||||
* require this script from your main lua file
|
||||
* trigger conversion on selected/hovered images by shortcut (set shortcut in settings dialog)
|
||||
* it is also possible to have the script run after importing a collection (optin, since it is not that fast)
|
||||
]]
|
||||
|
||||
local darktable = require "darktable"
|
||||
|
||||
-- Tested with darktable 1.6.2
|
||||
darktable.configuration.check_version(...,{2,0,2})
|
||||
|
||||
local queue = {}
|
||||
local processed_files = {}
|
||||
local job
|
||||
|
||||
local function file_imported(event, image)
|
||||
local filename = image.path .. "/" .. image.filename
|
||||
if processed_files[filename] then
|
||||
image.make_group_leader(image)
|
||||
processed_files[filename] = false
|
||||
else
|
||||
if darktable.preferences.read("cr2hdr", "onimport", "bool") then
|
||||
table.insert(queue, image)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function stop_conversion(job)
|
||||
job.valid = false
|
||||
end
|
||||
|
||||
local function convert_image(image)
|
||||
if string.sub(image.filename, -3) == "CR2" then
|
||||
local filename = image.path .. "/" .. image.filename
|
||||
local result = coroutine.yield("RUN_COMMAND", "cr2hdr " .. filename)
|
||||
local out_filename = string.gsub(filename, ".CR2", ".DNG")
|
||||
local file = io.open(out_filename)
|
||||
if file then
|
||||
file:close()
|
||||
processed_files[out_filename] = true
|
||||
darktable.database.import(out_filename)
|
||||
else
|
||||
darktable.print_error(filename .. ": cr2hdr failed.")
|
||||
end
|
||||
else
|
||||
darktable.print_error(image.filename .. " is not a Canon RAW.")
|
||||
end
|
||||
end
|
||||
|
||||
local function convert_images()
|
||||
if next(queue) == nil then return end
|
||||
|
||||
job = darktable.gui.create_job("Dual ISO conversion", true, stop_conversion)
|
||||
for key,image in pairs(queue) do
|
||||
if job.valid then
|
||||
job.percent = (key-1)/#queue
|
||||
convert_image(image)
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
local success_count = 0
|
||||
for _ in pairs(processed_files) do success_count = success_count + 1 end
|
||||
darktable.print("Dual ISO conversion successful on " .. success_count .. "/" .. #queue .. " images.")
|
||||
job.valid = false
|
||||
processed_files = {}
|
||||
queue = {}
|
||||
end
|
||||
|
||||
local function film_imported(event, film)
|
||||
if darktable.preferences.read("cr2hdr", "onimport", "bool") then
|
||||
convert_images()
|
||||
end
|
||||
end
|
||||
|
||||
local function convert_action_images(shortcut)
|
||||
queue = darktable.gui.action_images
|
||||
convert_images()
|
||||
end
|
||||
|
||||
darktable.register_event("shortcut", convert_action_images, "Run cr2hdr (Magic Lantern DualISO converter) on selected images")
|
||||
darktable.register_event("post-import-image", file_imported)
|
||||
darktable.register_event("post-import-film", film_imported)
|
||||
|
||||
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)
|
||||
@@ -104,7 +104,7 @@ local function create_kml_file(storage, image_table, extra_data)
|
||||
-- Creates dir if not exsists
|
||||
imageFoldername = "files/"
|
||||
local mkdirCommand = "mkdir -p "..exportDirectory.."/"..imageFoldername
|
||||
coroutine.yield("run_command", mkdirCommand)
|
||||
coroutine.yield("RUN_COMMAND", mkdirCommand)
|
||||
end
|
||||
|
||||
|
||||
@@ -122,9 +122,9 @@ local function create_kml_file(storage, image_table, extra_data)
|
||||
|
||||
local concertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg"
|
||||
-- USE coroutine.yield. It does not block the UI
|
||||
coroutine.yield("run_command", concertToThumbCommand)
|
||||
coroutine.yield("RUN_COMMAND", concertToThumbCommand)
|
||||
local concertCommand = "convert -size 438x438 "..image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg"
|
||||
coroutine.yield("run_command", concertCommand)
|
||||
coroutine.yield("RUN_COMMAND", concertCommand)
|
||||
|
||||
local pattern = "[/]?([^/]+)$"
|
||||
filmName = string.match(_.film.path, pattern)
|
||||
@@ -222,7 +222,7 @@ local function create_kml_file(storage, image_table, extra_data)
|
||||
local createKMZCommand = "zip --test --move --junk-paths "
|
||||
createKMZCommand = createKMZCommand .."\""..exportDirectory.."/"..exportKMZFilename.."\" "
|
||||
createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..exportKMLFilename.."\" \""..dt.configuration.tmp_dir.."/"..imageFoldername.."\"*"
|
||||
coroutine.yield("run_command", createKMZCommand)
|
||||
coroutine.yield("RUN_COMMAND", createKMZCommand)
|
||||
end
|
||||
|
||||
-- Open the file with the standard programm
|
||||
@@ -234,7 +234,7 @@ local function create_kml_file(storage, image_table, extra_data)
|
||||
else
|
||||
kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMLFilename.."\""
|
||||
end
|
||||
coroutine.yield("run_command", kmlFileOpenCommand)
|
||||
coroutine.yield("RUN_COMMAND", kmlFileOpenCommand)
|
||||
end
|
||||
|
||||
|
||||
@@ -253,4 +253,3 @@ dt.preferences.register("kml_export", "CreateKMZ", "bool", "KML export: Create K
|
||||
|
||||
-- Register
|
||||
dt.register_storage("kml_export", "KML/KMZ Export", nil, create_kml_file)
|
||||
|
||||
|
||||
@@ -59,9 +59,11 @@ local function playSlideshowMusic(_, old_view, new_view)
|
||||
--dt.print_error(playCommand)
|
||||
coroutine.yield("RUN_COMMAND", playCommand)
|
||||
else
|
||||
stopCommand = "rhythmbox-client --pause"
|
||||
--dt.print_error(stopCommand)
|
||||
coroutine.yield("RUN_COMMAND", stopCommand)
|
||||
if (old_view.id == "slideshow") then
|
||||
stopCommand = "rhythmbox-client --pause"
|
||||
--dt.print_error(stopCommand)
|
||||
coroutine.yield("RUN_COMMAND", stopCommand)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -90,14 +90,14 @@ local function create_video(storage, image_table, extra_data)
|
||||
|
||||
dt.print_error("this is the command: "..command)
|
||||
-- USE coroutine.yield. It does not block the UI
|
||||
coroutine.yield("run_command", command)
|
||||
coroutine.yield("RUN_COMMAND", command)
|
||||
|
||||
dt.print("Video created in "..exportDirectory)
|
||||
|
||||
if ( dt.preferences.read("video","OpenVideo","bool") == true ) then
|
||||
-- USE coroutine.yield. It does not block the UI
|
||||
local playVideoCommand = "xdg-open "..exportDirectory.."/"..exportFilename
|
||||
coroutine.yield("run_command", playVideoCommand)
|
||||
coroutine.yield("RUN_COMMAND", playVideoCommand)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -115,4 +115,3 @@ dt.preferences.register("video", "Codec", "enum", "Video exort: Codec","Video co
|
||||
|
||||
-- Register
|
||||
dt.register_storage("video", "Video Export", show_status, create_video)
|
||||
|
||||
|
||||
63
official/image_path_in_ui.lua
Normal file
63
official/image_path_in_ui.lua
Normal file
@@ -0,0 +1,63 @@
|
||||
--[[
|
||||
This file is part of darktable,
|
||||
copyright (c) 2014 Jérémy Rosen
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
IMAGE_PATH_IN_UI
|
||||
Add a widget with the path of the selected images for easy copy/past
|
||||
Simple shortcuts to have multiple selection bufers
|
||||
|
||||
|
||||
USAGE
|
||||
* require this file from your main lua config file:
|
||||
|
||||
This plugin will add a widget at the bottom of the left column in lighttable mode
|
||||
|
||||
|
||||
]]
|
||||
local dt = require "darktable"
|
||||
dt.configuration.check_version(...,{2,0,0})
|
||||
|
||||
local main_label = dt.new_widget("label"){selectable = true}
|
||||
|
||||
local function reset_widget()
|
||||
local selection = dt.gui.selection()
|
||||
local result = ""
|
||||
local array = {}
|
||||
for _,img in pairs(selection) do
|
||||
array[img.path] = true
|
||||
end
|
||||
for path in pairs(array) do
|
||||
if result == "" then
|
||||
result = path
|
||||
else
|
||||
result = result.."\n"..path
|
||||
end
|
||||
end
|
||||
main_label.label = result
|
||||
end
|
||||
|
||||
main_label.reset_callback = reset_widget
|
||||
|
||||
dt.register_lib("image_path_no_ui","Selected Images path",true,false,{
|
||||
[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_CENTER",300}
|
||||
}, main_label
|
||||
);
|
||||
|
||||
dt.register_event("mouse-over-image-changed",reset_widget);
|
||||
|
||||
--
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
79
official/import_filter_manager.lua
Normal file
79
official/import_filter_manager.lua
Normal file
@@ -0,0 +1,79 @@
|
||||
--[[
|
||||
This file is part of darktable,
|
||||
copyright (c) 2015 Tobias Ellinghaus
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
IMPORT FILTER MANAGER
|
||||
This script adds a dropdown list with import filters to the import dialog.
|
||||
Scripts can add new filters by registering them with
|
||||
darktable.register_import_filter(name, callback)
|
||||
The callback has type function(event, images), i.e., it is the same as when
|
||||
directly registering the pre-import event.
|
||||
|
||||
|
||||
USAGE
|
||||
* require this script from your main lua file
|
||||
* also require some files with import filters, for example import_filters.lua.
|
||||
it is important to add them AFTER this one!
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
|
||||
local import_filter_list = {}
|
||||
local n_import_filters = 1
|
||||
|
||||
-- allow changing the filter from the preferences
|
||||
dt.preferences.register("import_filter_manager", "active_filter", "string",
|
||||
"import filter", "the name of the filter used for importing images", "")
|
||||
|
||||
|
||||
-- the dropdown to select the active filter from the import dialog
|
||||
local filter_dropdown = dt.new_widget("combobox")
|
||||
{
|
||||
label = "import filter",
|
||||
editable = false,
|
||||
|
||||
changed_callback = function(widget)
|
||||
dt.preferences.write("import_filter_manager", "active_filter", "string", widget.value)
|
||||
end,
|
||||
|
||||
"" -- the first entry in the list is hard coded to "" so it's possible to have no filter
|
||||
}
|
||||
dt.gui.libs.import.register_widget(filter_dropdown)
|
||||
|
||||
|
||||
-- this is just a wrapper which calls the active import filter
|
||||
dt.register_event("pre-import", function(event, images)
|
||||
local active_filter = dt.preferences.read("import_filter_manager", "active_filter", "string")
|
||||
if active_filter == "" then return end
|
||||
local callback = import_filter_list[active_filter]
|
||||
if callback then callback(event, images) end
|
||||
end)
|
||||
|
||||
|
||||
-- add a new global function to register import filters
|
||||
dt.register_import_filter = function(name, callback)
|
||||
local active_filter = dt.preferences.read("import_filter_manager", "active_filter", "string")
|
||||
dt.print_error("registering import filter `" .. name .. "'")
|
||||
import_filter_list[name] = callback
|
||||
n_import_filters = n_import_filters + 1
|
||||
filter_dropdown[n_import_filters] = name
|
||||
if name == active_filter then filter_dropdown.value = n_import_filters end
|
||||
end
|
||||
|
||||
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent
|
||||
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
|
||||
80
official/import_filters.lua
Normal file
80
official/import_filters.lua
Normal file
@@ -0,0 +1,80 @@
|
||||
--[[
|
||||
This file is part of darktable,
|
||||
copyright (c) 2015 Tobias Ellinghaus
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
EXAMPLE IMPORT FILTERS
|
||||
This script goes along with the import filter manager. It adds two filters:
|
||||
* ignore jpegs: this one does the same as the existing option in the import dialog
|
||||
and just skips all JPEGs during import.
|
||||
* prefer raw over jpeg: this one is a bit more elaborate, it ignores JPEGs when there
|
||||
is also another file with the same basename, otherwise it
|
||||
allows JPEGs, too.
|
||||
|
||||
USAGE
|
||||
* require this script from your main lua file AFTER import_filter_manager.lua
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
|
||||
-- we get fed a sorted list of filenames. just setting images to ignore to nil is enough
|
||||
|
||||
-- ignore jpeg
|
||||
dt.register_import_filter("ignore jpegs", function(event, images)
|
||||
dt.print_error("ignoring all jpegs")
|
||||
for i, img in ipairs(images) do
|
||||
local extension = img:match("[^.]*$"):upper()
|
||||
if (extension == "JPG") or (extension == "JPEG") then
|
||||
images[i] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
-- ignore jpeg iff another format for the image is found
|
||||
dt.register_import_filter("prefer raw over jpeg", function(event, images)
|
||||
dt.print_error("prefering raw over jpeg")
|
||||
local current_base = ""
|
||||
local jpg_indices = {}
|
||||
local other_format_found = false
|
||||
for i, img in ipairs(images) do
|
||||
local extension = img:match("[^.]*$"):upper()
|
||||
local base = img:match("^.*[.]")
|
||||
|
||||
if base ~= current_base then
|
||||
-- we are done with the base name, act according to what we found out
|
||||
if other_format_found then
|
||||
for _, jpg in ipairs(jpg_indices) do
|
||||
images[jpg] = nil
|
||||
end
|
||||
end
|
||||
current_base = base
|
||||
other_format_found = false
|
||||
for k,_ in pairs(jpg_indices) do jpg_indices[k] = nil end
|
||||
end
|
||||
|
||||
-- remember what we have here to act accordingly after all instances of this base name were checked
|
||||
if (extension == "JPG") or (extension == "JPEG") then
|
||||
table.insert(jpg_indices, i)
|
||||
else
|
||||
other_format_found = true
|
||||
end
|
||||
|
||||
end
|
||||
end)
|
||||
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent
|
||||
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;
|
||||
154
official/selection_to_pdf.lua
Normal file
154
official/selection_to_pdf.lua
Normal file
@@ -0,0 +1,154 @@
|
||||
--[[
|
||||
This file is part of darktable,
|
||||
copyright (c) 2015 Jérémy Rosen & Pascal Obry
|
||||
|
||||
darktable is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
darktable is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
SELECTION_TO_PDF
|
||||
Generates a PDF file (via Latex) containing all selected images
|
||||
|
||||
ADDITIANAL SOFTWARE NEEDED FOR THIS SCRIPT
|
||||
* a PDF-Viewer
|
||||
* pdflatex (Latex)
|
||||
|
||||
USAGE
|
||||
* require this file from your main lua config file:
|
||||
|
||||
This plugin will add a new exporter that will allow you to generate the pdf file
|
||||
|
||||
|
||||
]]
|
||||
local dt = require "darktable"
|
||||
dt.configuration.check_version(...,{2,0,0})
|
||||
|
||||
dt.preferences.register
|
||||
("selection_to_pdf","Open with","string",
|
||||
"a pdf viewer",
|
||||
"Can be an absolute pathname or the tool may be in the PATH",
|
||||
"xdg-open")
|
||||
|
||||
local title_widget = dt.new_widget("entry") {
|
||||
placeholder="Title"
|
||||
}
|
||||
local widget = dt.new_widget("box") {
|
||||
orientation=horizontal,
|
||||
dt.new_widget("label"){label = "Title:"},
|
||||
title_widget
|
||||
}
|
||||
|
||||
local ending = [[
|
||||
\end{document}
|
||||
]]
|
||||
|
||||
local thumbs_per_line=4;
|
||||
local width = 1/thumbs_per_line-0.01
|
||||
|
||||
local filename =dt.configuration.tmp_dir.."/pdfout.tex"
|
||||
|
||||
local function my_write(latexfile,arg)
|
||||
local res,errmsg = latexfile:write(arg)
|
||||
if not res then
|
||||
error(errmsg)
|
||||
end
|
||||
end
|
||||
|
||||
local function thumbnail(latexfile,i,image,file)
|
||||
local title
|
||||
if image.title == "" then
|
||||
title = image.filename
|
||||
if image.duplicate_index > 0 then
|
||||
title = title.."["..image.duplicate_index.."]"
|
||||
end
|
||||
|
||||
else
|
||||
title = image.title
|
||||
end
|
||||
|
||||
-- fact is that latex will get confused if the filename has multiple dots.
|
||||
-- so \includegraphics{file.01.jpg} wont work. We need to output the filename
|
||||
-- and extention separated, e.g: \includegraphics{{file.01}.jpg}
|
||||
local filenoext=string.gsub(file, "(.*)(%..*)", "%1")
|
||||
local ext=string.gsub(file, "(.*)(%..*)", "%2")
|
||||
my_write(latexfile,"\\begin{minipage}[b]{"..width.."\\textwidth}\n")
|
||||
my_write(latexfile,"\\includegraphics[width=\\textwidth]{{"..filenoext.."}"..ext.."}\\newline\n")
|
||||
my_write(latexfile,"\\centering{"..i..": \\verb|"..title.."|}\n")
|
||||
my_write(latexfile,"\\end{minipage}\\quad\n")
|
||||
end
|
||||
|
||||
dt.register_storage("export_pdf","Export thumbnails to pdf",
|
||||
nil,
|
||||
function(storage,image_table)
|
||||
local my_title = title_widget.text
|
||||
if my_title == "" then
|
||||
my_title = "Title"
|
||||
end
|
||||
local preamble = [[
|
||||
\documentclass[a4paper,10pt]{article}
|
||||
\usepackage{graphicx}
|
||||
\pagestyle{empty}
|
||||
\parindent0pt
|
||||
\usepackage{geometry}
|
||||
\geometry{a4paper,left=5mm,right=5mm, top=5mm, bottom=5mm}
|
||||
\begin{document}
|
||||
{\Large\bfseries ]]..my_title..[[} \\
|
||||
\bigskip\bigskip
|
||||
]]
|
||||
|
||||
local errmsg
|
||||
local latexfile
|
||||
latexfile,errmsg=io.open(filename,"w")
|
||||
if not latexfile then
|
||||
error(errmsg)
|
||||
end
|
||||
my_write(latexfile,preamble)
|
||||
local i = 1
|
||||
for img,file in pairs(image_table) do
|
||||
thumbnail(latexfile,i,img,file)
|
||||
if i % thumbs_per_line == 0 then
|
||||
my_write(latexfile,"\n\\bigskip\n")
|
||||
end
|
||||
i = i+1
|
||||
end
|
||||
my_write(latexfile,ending)
|
||||
latexfile:close()
|
||||
|
||||
-- convert to PDF
|
||||
local dir=string.gsub(filename, "(.*/)(.*)", "%1")
|
||||
local locfile=string.gsub(filename, "(.*/)(.*)", "%2")
|
||||
local command = "pdflatex -halt-on-error -output-directory "..dir.." "..locfile
|
||||
local result = coroutine.yield("RUN_COMMAND",command)
|
||||
if result ~= 0 then
|
||||
dt.print("Problem running pdflatex") -- this one is probably usefull to the user
|
||||
error("Problem running "..command)
|
||||
end
|
||||
|
||||
-- open the PDF
|
||||
local pdffile=string.gsub(filename, ".tex", ".pdf")
|
||||
command = dt.preferences.read("selection_to_pdf","Open with","string")
|
||||
command = command.." "..pdffile
|
||||
local result = coroutine.yield("RUN_COMMAND",command)
|
||||
if result ~= 0 then
|
||||
dt.print("Problem running pdf viewer") -- this one is probably usefull to the user
|
||||
error("Problem running "..command)
|
||||
end
|
||||
|
||||
-- finally do some clean-up
|
||||
for img,file in pairs(image_table) do
|
||||
os.remove(file)
|
||||
end
|
||||
end,nil,nil,widget)
|
||||
|
||||
--
|
||||
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua
|
||||
Reference in New Issue
Block a user