Copy link to clipboard
Copied
I am attempting to get a Red-Blue channel swap LR plugin to work on Windows.
See:-
and
The plugin uses Imagemagick:-
convert img.jpg -set colorspace RGB -separate -swap 0,2 -combine img.jpg
or
magick img.jpg -set colorspace RGB -separate -swap 0,2 -combine img.jpg
This works fine if I execute the command from a command window.
However it doesn't work when executed from the plugin using LrTasks.execute().
The resulting jpg file does not have the channels swapped.
I'm new to the lua scripting language.
Here is the code:-
--
-- Quick Export Script to Swap Red and Blue Channels in Gimp
-- by Stu Fisher http://q3f.org
--
-- modified to use ImageMagick
-- by Chris McClanahan http://mcclanahoochie.com
-- http://mcclanahoochie.com/blog/2013/01/lightroom-plugins-infrared-and-pyrdetail
--
local LrTasks = import 'LrTasks'
local LrApplication = import 'LrApplication'
local LrLogger = import 'LrLogger'
local myLogger = LrLogger('RBSwap')
myLogger:enable("print")
exportServiceProvider = {}
exportServiceProvider.canExportVideo = false
function exportServiceProvider.processRenderedPhotos(functionContext, exportContext)
local exportSession = exportContext.exportSession
local exportSettings = exportContext.propertyTable
local nPhotos = exportSession:countRenditions()
local progressScope = exportContext:configureProgress {
title =
nPhotos > 1 and LOC("$$$/RBSwap/Publish/Progress=Exporting ^1 photos to RB swap", nPhotos)
or LOC "$$$/RBSwap/Publish/Progress/One=Exporting one photo to RB swap",
}
for i, rendition in exportContext:renditions { stopIfCanceled = true } do
progressScope:setPortionComplete((i - 1) / nPhotos)
if not rendition.wasSkipped then
local success, pathOrMessage = rendition:waitForRender()
progressScope:setPortionComplete((i - 0.5) / nPhotos)
if progressScope:isCanceled() then break end
if success then
local filePath = assert(pathOrMessage)
-- choose app, configure bin paths --
--result = LrTasks.execute("/Applications/Gimp-2.8.app/Contents/Resources/bin/gimp-2.8 -i -b '(red_blue_swap \"" .. filePath .. "\")' -b '(gimp-quit 0)'")
if WIN_ENV then
-- windows support thanks to Frank Firsching
cmd = "cmd.exe /c convert.exe"
else
cmd = "/opt/local/bin/convert"
end
local cmd = cmd .. " " .. filePath .. " -set colorspace RGB -separate -swap 0,2 -combine " .. filePath
result = LrTasks.execute(cmd)
-- no need to trigger import. Done automatically by Lightroom as
-- specified in presets/RBSwap.lrtemplate
end
end
end
progressScope:done()
end
return exportServiceProvider
I've tried adding a debug line to see if LrTasks.execute() is working:-
result = LrTasks.execute("echo 'test' > ~\\Desktop\\log.txt")
I get no log.txt file, so either I'm doing something wrong or LrTasks.execute() is not working at all.
I've tried all sorts of combinations of quoting and escape characters in the string.
Nothing seems to work.
I know the execute() function is being called because if I add 'error(cmd)' just before
LrTasks.execute(cmd) I get an error window showing the command string.
I've run out of ideas to try.
Copy link to clipboard
Copied
Skimming your code, some thoughts come to mind:
- You're not quoting the filePath argument, which is a problem if the path contains spaces.
- On Windows, you need to wrap the entire command line with an additional set of double quotes. (Who knows why, it's just magic that's needed.)
- To see what's going on, you need to check the exit code from execute() and also standard out and standard error (in case there are error messages).
- I posted the source for my Util.safeExecute() function which takes care of the Windows need for additional quotes and makes it easy to capture standard out and standard error: Re: LrTasks.execute return code 65280?
- I don't think your test line will work on either Windows or Mac:
LrTasks.execute("echo 'test' > ~\\Desktop\\log.txt")
On Windows, "~" doesn't expand to the user's home directory. On Mac, you need "/", not "\", as the path separator.
- Because the LR execution environment is so minimal, you really need to use a debugger when developing plugins. See here for more details: Re: Sample code for a publish service? . It will take you a couple hours to get one hooked up and get up to speed with it, but it will pay off immediately.
Copy link to clipboard
Copied
I eventually managed to get this to work after a lot of frustration and various combinations of escaping and quoting in strings.
First you need to escape backslashes in the Windows path names by converting '\' to '\\' in the file path string something like this:-
local filePath = string.gsub(assert(pathOrMessage),"\\","\\\\")
Then you need to surround the path name strings with double quotes to cope with spaces in the file names like this:-
('"' below is actually a double quote surrounded by single quotes)
filePath = '"' .. filePath .. '"'
Finally we can issue the command like this:-
if WIN_ENV then
cmd = "magick"
else
cmd = "/opt/local/bin/convert"
end
local cmd = cmd .. " " .. filePath .. " -set colorspace RGB -separate -swap 0,2 -combine " .. filePath
result = LrTasks.execute(cmd)
It is not necessary to launch a command window using cmd = "cmd.exe -c convert" as was done in the original script.
It is not necessary to wrap the entire command line with additional double quotes.
The debug test line I tried that didn't work actually came from your own previous suggestion! See:-
Problem with LrTasks.execute() method
This doesn't work because '~' does not expand to the user's home directory as you mention above.
To get it to work, I created a directory C:\Temp (with no spaces in the path name) and changed the debug line to:-
result = LrTasks.execute("echo 'test' > C:\\Temp\\log.txt")
As a retired software engineer with many years of experience on both Linux & Windows, I think the way lua handles quotes and escape characters is the most arcane (and poorly documented) features in any scripting language I have ever come across.
This link I found helps explain some of the quirks and bizarre behaviour:-
Escaping File Paths in Scripts
With so many far better scripting languages to choose from I do wonder why Adobe chose lua for lightroom plugins?
Copy link to clipboard
Copied
BTW: While debugging this plugin, I found the image icon displayed in Windows Explorer is not automatically refreshed following the RB swap.
Explorer continues to display the cached icon that was saved before to the channel swap. You have to manually refresh the window to see the updated image.
Copy link to clipboard
Copied
I should have added that 'magick.exe' and 'convert.exe' do the the same thing.
I seem to remember that 'convert' clashes with a built in command of the same name in Windows, so 'magick' is preferred to avoid confusion.
The code assumes that the path to magick.exe is in the users 'Path' environment variable.
You can check using $Env:Path in a PowerShell window.
It's easy enough to add the full path to magick.exe or convert.exe if required, but the same rules about escaping '\' and adding double quotes to allow spaces apply. I think it's probably better to rely on the 'Path' environment variable to locate the exe file, otherwise the plugin script would need to be changed if imagemagick is updated to a different version.
Copy link to clipboard
Copied
The debug test line I tried that didn't work actually came from your own previous suggestion! See:-
That example was for Mac OS, which the original poster in that thread was using:
LrTasks.execute ("echo A > ~/Desktop/log.txt")
Copy link to clipboard
Copied
you need to escape backslashes in the Windows path names by converting '\' to '\\' in the file path string something like this:-
local filePath = string.gsub(assert(pathOrMessage),"\\","\\\\")
That isn't necessary. You just need to double-quote file paths in case they contain spaces or other special characters. This example works correctly:
LrTasks.execute ([[echo A > "c:\users\john\my log.txt"]])
Copy link to clipboard
Copied
Thanks John. You are right.
When I was initially trying to get this to work I ended up changing things step by step and checking the resulting command string by writing to a log file.
Initially there were no surrounding double quotes, so escaping the backslashes in the file path was necessary.
Subsequently I added the quotes to fix the spaces in filenames issue.
I didn't realise that the additional quotes meant there was now no need to escape the backslashes.
I don't think the original script could have been tested with spaces in filenames under Windows.
I've now also changed things so that I export a RB channel swapped TIF file rather than JPG.
Imagemagick threw up some warnings about TIF tags, but it looks like they can be ignored.
'magick -quiet' removes the warnings.
Copy link to clipboard
Copied
It is not necessary to wrap the entire command line with additional double quotes.
That's only necessary if the program path contains spaces and is quoted. That doesn't appear to be the case in your example, so double-quoting the entire command line isn't needed. (This is a Windows issue, not a Lua issue.)
Copy link to clipboard
Copied
Just another idea, I followed this tutorial and can convert infrared pictures in Lr.