Skip to content

Commit f61a710

Browse files
committed
Merge pull request #55 from wpferguson/master
External editing with GIMP
2 parents e3f1ff7 + 4577317 commit f61a710

File tree

2 files changed

+297
-0
lines changed

2 files changed

+297
-0
lines changed

contrib/de_DE/LC_MESSAGES/gimp.po

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# SOME DESCRIPTIVE TITLE.
2+
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3+
# This file is distributed under the same license as the PACKAGE package.
4+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5+
#
6+
msgid ""
7+
msgstr ""
8+
"Project-Id-Version: gimp\n"
9+
"Report-Msgid-Bugs-To: \n"
10+
"POT-Creation-Date: 2016-04-13 23:50-0400\n"
11+
"PO-Revision-Date: 2016-04-14 00:11-0500\n"
12+
"Last-Translator: Bill Ferguson <wpferguson@gmail.com>\n"
13+
"Language-Team: LANGUAGE <LL@li.org>\n"
14+
"MIME-Version: 1.0\n"
15+
"Content-Type: text/plain; charset=UTF-8\n"
16+
"Content-Transfer-Encoding: 8bit\n"
17+
"X-Generator: Poedit 1.5.4\n"
18+
"Language: de_DE\n"
19+
"X-Poedit-SourceCharset: UTF-8\n"
20+
"X-Poedit-KeywordsList: gettext;dgettext:2;dcgettext:2ngettext:1,2;"
21+
"dngettext:2,3\n"
22+
"X-Poedit-Basepath: .\n"
23+
24+
#: gimp.lua:189
25+
#, lua-format
26+
msgid "Export Image %i/%i"
27+
msgstr "Exportiere Bild %i/%i"
28+
29+
#: gimp.lua:194
30+
msgid "GIMP not found"
31+
msgstr "GIMP nicht gefunden"
32+
33+
#: gimp.lua:209
34+
msgid "Launching GIMP..."
35+
msgstr "Starten von GIMP"
36+
37+
#: gimp.lua:254
38+
msgid "Edit with GIMP"
39+
msgstr "Bearbeiten mit GIMP"

contrib/gimp.lua

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
--[[
2+
3+
gimp.lua - export and edit with GIMP
4+
5+
Copyright (C) 2016 Bill Ferguson <wpferguson@gmail.com>.
6+
7+
Portions are lifted from hugin.lua and thus are
8+
9+
Copyright (c) 2014 Wolfgang Goetz
10+
Copyright (c) 2015 Christian Kanzian
11+
Copyright (c) 2015 Tobias Jakobs
12+
13+
14+
This program is free software: you can redistribute it and/or modify
15+
it under the terms of the GNU General Public License as published by
16+
the Free Software Foundation; either version 3 of the License, or
17+
(at your option) any later version.
18+
19+
This program is distributed in the hope that it will be useful,
20+
but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
GNU General Public License for more details.
23+
24+
You should have received a copy of the GNU General Public License
25+
along with this program. If not, see <http://www.gnu.org/licenses/>.
26+
]]
27+
--[[
28+
gimp - export an image and open with GIMP for editing
29+
30+
This script provides another storage (export target) for darktable. Selected
31+
images are exported in the specified format to temporary storage. GIMP is launched
32+
and opens the files. After editing, the exported images are overwritten to save the
33+
changes. When GIMP exits, the exported files are moved into the current collection
34+
and imported into the database. The imported files then show up grouped with the
35+
originally selected images.
36+
37+
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
38+
* GIMP - http://www.gimp.org
39+
40+
USAGE
41+
* require this script from your main lua file
42+
* select an image or images for editing with GIMP
43+
* in the export dialog select "Edit with GIMP" and select the format and bit depth for the
44+
exported image
45+
* Press "export"
46+
* Edit the image with GIMP then save the changes with File->Overwrite....
47+
* Exit GIMP
48+
* The edited image will be imported and grouped with the original image
49+
50+
CAVEATS
51+
* Developed and tested on Ubuntu 14.04 LTS with darktable 2.0.3 and GIMP 2.9.3 (development version with
52+
> 8 bit color)
53+
* There is no provision for dealing with the xcf files generated by GIMP, since darktable doesn't deal with
54+
them. You may want to save the xcf file if you intend on doing further edits to the image or need to save
55+
the layers used. Where you save them is up to you.
56+
57+
BUGS, COMMENTS, SUGGESTIONS
58+
* Send to Bill Ferguson, wpferguson@gmail.com
59+
]]
60+
61+
local dt = require "darktable"
62+
local gettext = dt.gettext
63+
64+
dt.configuration.check_version(...,{3,0,0})
65+
66+
-- Tell gettext where to find the .mo file translating messages for a particular domain
67+
gettext.bindtextdomain("gimp",dt.configuration.config_dir.."/lua/")
68+
69+
local function split_filepath(str)
70+
local result = {}
71+
-- Thank you Tobias Jakobs for the awesome regular expression, which I tweaked a little
72+
result["path"], result["filename"], result["basename"], result["filetype"] = string.match(str, "(.-)(([^\\/]-)%.?([^%.\\/]*))$")
73+
return result
74+
end
75+
76+
local function get_path(str)
77+
local parts = split_filepath(str)
78+
return parts["path"]
79+
end
80+
81+
local function get_filename(str)
82+
local parts = split_filepath(str)
83+
return parts["filename"]
84+
end
85+
86+
local function get_basename(str)
87+
local parts = split_filepath(str)
88+
return parts["basename"]
89+
end
90+
91+
local function get_filetype(str)
92+
local parts = split_filepath(str)
93+
return parts["filetype"]
94+
end
95+
96+
local function _(msgid)
97+
return gettext.dgettext("gimp", msgid)
98+
end
99+
100+
local function checkIfBinExists(bin)
101+
local handle = io.popen("which "..bin)
102+
local result = handle:read()
103+
local ret
104+
handle:close()
105+
if (result) then
106+
dt.print_error("true checkIfBinExists: "..bin)
107+
ret = true
108+
else
109+
dt.print_error(bin.." not found")
110+
ret = false
111+
end
112+
return ret
113+
end
114+
115+
-- Thanks Tobias Jakobs for the idea and the correction
116+
function checkIfFileExists(filepath)
117+
local file = io.open(filepath,"r")
118+
local ret
119+
if file ~= nil then
120+
io.close(file)
121+
dt.print_error("true checkIfFileExists: "..filepath)
122+
ret = true
123+
else
124+
dt.print_error(filepath.." not found")
125+
ret = false
126+
end
127+
return ret
128+
end
129+
130+
local function filename_increment(filepath)
131+
132+
-- break up the filepath into parts
133+
local path = get_path(filepath)
134+
local basename = get_basename(filepath)
135+
local filetype = get_filetype(filepath)
136+
137+
-- check to see if we've incremented before
138+
local increment = string.match(basename, "_(%d-)$")
139+
140+
if increment then
141+
-- we do 2 digit increments so make sure we didn't grab part of the filename
142+
if string.len(increment) > 2 then
143+
-- we got the filename so set the increment to 01
144+
increment = "01"
145+
else
146+
increment = string.format("%02d", tonumber(increment) + 1)
147+
basename = string.gsub(basename, "_(%d-)$", "")
148+
end
149+
else
150+
increment = "01"
151+
end
152+
local incremented_filepath = path .. basename .. "_" .. increment .. "." .. filetype
153+
154+
dt.print_error("original file was " .. filepath)
155+
dt.print_error("incremented file is " .. incremented_filepath)
156+
157+
return incremented_filepath
158+
end
159+
160+
local function groupIfNotMember(img, new_img)
161+
local image_table = img:get_group_members()
162+
local is_member = false
163+
for _,image in ipairs(image_table) do
164+
dt.print_error(image.filename .. " is a member")
165+
if image.filename == new_img.filename then
166+
is_member = true
167+
dt.print_error("Already in group")
168+
end
169+
end
170+
if not is_member then
171+
dt.print_error("group leader is "..img.group_leader.filename)
172+
new_img:group_with(img.group_leader)
173+
dt.print_error("Added to group")
174+
end
175+
end
176+
177+
local function sanitize_filename(filepath)
178+
local path = get_path(filepath)
179+
local basename = get_basename(filepath)
180+
local filetype = get_filetype(filepath)
181+
182+
local sanitized = string.gsub(basename, " ", "\\ ")
183+
184+
return path .. sanitized .. "." .. filetype
185+
end
186+
187+
local function show_status(storage, image, format, filename,
188+
number, total, high_quality, extra_data)
189+
dt.print(string.format(_("Export Image %i/%i"), number, total))
190+
end
191+
192+
local function gimp_edit(storage, image_table, extra_data) --finalize
193+
if not checkIfBinExists("gimp") then
194+
dt.print_error(_("GIMP not found"))
195+
return
196+
end
197+
198+
-- list of exported images
199+
local img_list
200+
201+
-- reset and create image list
202+
img_list = ""
203+
204+
for _,exp_img in pairs(image_table) do
205+
exp_img = sanitize_filename(exp_img)
206+
img_list = img_list ..exp_img.. " "
207+
end
208+
209+
dt.print(_("Launching GIMP..."))
210+
211+
local gimpStartCommand
212+
gimpStartCommand = "gimp "..img_list
213+
214+
dt.print_error(gimpStartCommand)
215+
216+
coroutine.yield("RUN_COMMAND", gimpStartCommand)
217+
218+
-- for each of the image, exported image pairs
219+
-- move the exported image into the directory with the original
220+
-- then import the image into the database which will group it with the original
221+
-- and then copy over any tags other than darktable tags
222+
223+
for image,exported_image in pairs(image_table) do
224+
225+
local myimage_name = image.path .. "/" .. get_filename(exported_image)
226+
227+
while checkIfFileExists(myimage_name) do
228+
myimage_name = filename_increment(myimage_name)
229+
-- limit to 99 more exports of the original export
230+
if string.match(get_basename(myimage_name), "_(d-)$") == "99" then
231+
break
232+
end
233+
end
234+
235+
dt.print_error("moving " .. exported_image .. " to " .. myimage_name)
236+
result = os.rename(exported_image, myimage_name)
237+
238+
dt.print_error("importing file")
239+
local myimage = dt.database.import(myimage_name)
240+
241+
groupIfNotMember(image, myimage)
242+
243+
for _,tag in pairs(dt.tags.get_tags(image)) do
244+
if not (string.sub(tag.name,1,9) == "darktable") then
245+
dt.print_error("attaching tag")
246+
dt.tags.attach(tag,myimage)
247+
end
248+
end
249+
end
250+
251+
end
252+
253+
-- Register
254+
dt.register_storage("module_gimp", _("Edit with GIMP"), show_status, gimp_edit)
255+
256+
--
257+
258+

0 commit comments

Comments
 (0)