0

I'd like to add a right click menu item to easily resize images in files.

I found that the following script does what I want when I run it in a Terminal:

convert myimage.jpg -resize '1200x1200' -set filename:fname '%t-1200px.%e' +adjoin '%[filename:fname]'

But when add a resize-image.contract file to ~/.local/share/contractor with the following content, nothing seems to happen.

[Contractor Entry]
Name=Resize to 1200px
MimeType=image;
Exec=convert %U -resize '1200x1200' -set filename:fname '%t-1200px.%e' +adjoin '%[filename:fname]'
Gettext-Domain=pantheon-terminal

(This scripts requires imagemagick)

Is there a way to debug this? When I run pantheon-files --debug I don't see relevant output.

Issue on Contracts documentation: https://github.com/elementary/contractor/issues/16

Update: I've tried splitting up the script, like Jeremy Wootten suggested, see below, but that doesn't seem to help.

~/.local/share/contractor/resize-image-1200.contract:

[Contractor Entry]
Name=Resize to 1200px
MimeType=image;
Exec=convert %U -resize '1200x1200' -set filename:fname '%t-1200px.%e' +adjoin '%[filename:fname]'
Exec=/usr/local/bin/resize-image-1200.sh %U
Gettext-Domain=pantheon-terminal

/usr/local/bin/resize-image-1200.sh:

#!/bin/bash

inputfile=${1?'please supply input file name'}
echo "input: $inputfile"

convert $inputfile -resize '1200x1200' -set filename:fname '%t-1200px.%e' +adjoin '%[filename:fname]'

Update 2: With the tips from Jeremy Wootten I have something that kind of works, except that it doesn't use convert's rename trick, so now it's limited to jpg files.

~/.local/share/contractor/resize-image-1200.contract:

[Contractor Entry]
Name=Resize to 1200px
MimeType=image;
Exec=resize-image-1200.sh %U
Gettext-Domain=pantheon-terminal

/usr/local/bin/resize-image-1200.sh:

#!/bin/bash
convert "$1" -resize '1200x1200' "$1-test.jpg"

I've opened an issue on debugging .contract files: https://github.com/elementary/contractor/issues/20

Update 3: After a tip on debugging I changed my /usr/local/bin/resize-image-1200.sh script to:

#!/bin/bash
exec 2> /tmp/resize-image-1200.sh.log
exec 1>&2
set -x
convert "$1" -resize '1200x1200' -set filename:fname '%t-1200px.%e' '%[filename:fname]'

This created /tmp/resize-image-1200.sh.log with:

+ convert '/home/peteruithoven/NextCloud/InstantUpload/OpenScope/thunar test/IMG_20171116_003459.jpg' -resize 1200x1200 -set filename:fname %t-1200px.%e '%[filename:fname]'

Which indicates that it ran the script successfully. Running this myself I found out it would put the resulting resized image file in the folder I was executing the script from, so I think that's the next challenge.

Update 4: Instead of using Imagemagick to rename I'm now using bash functionality.

/usr/local/bin/resize-image-1200.sh:

#!/bin/bash
exec 2> /tmp/resize-image-1200.sh.log
exec 1>&2
set -x

DIR=$(dirname "$1")
BASENAME=$(basename "$1")
FILENAME=${BASENAME%.*}
EXT=${BASENAME##*.}

convert "$1" -resize '1200x1200' +adjoin "$DIR/$FILENAME-1200px.$EXT"

One downside is that this script wouldn't work with multiple files, but then again, even when selecting multiple files and running the contract the .sh script only gets the path to the first file.

2 Answers 2

2

So this was interesting. Like Jeremy Wootten mentioned what you can put behind a .contract Exec is limited. So calling a shell script is part of the solution. So step one is creating something like the following contract file:

~/.local/share/contractor:

[Contractor Entry]
Name=Resize to 1200px
MimeType=image;
Exec=resize-image-1200.sh %f
Gettext-Domain=pantheon-terminal

Another challenge was debugging, how to get output from the script, to see errors. Using exec, piping the output to a log file and set -x where a solution. I ended up with the following file:

/usr/local/bin/resize-image-1200.sh:

#!/bin/bash
exec 2> /tmp/resize-image-1200.sh.log # log errors to log file
exec 1>&2 # log standard output as errors
set -x # log commands before execution and log result

DIR=$(dirname "$1")
BASENAME=$(basename "$1")
FILENAME=${BASENAME%.*}
EXT=${BASENAME##*.}

convert "$1" -resize '1200x1200' "$DIR/$FILENAME-1200px.$EXT"

This file needs execution rights, so run:

$ sudo chmod +x /usr/local/bin/resize-image-1200.sh

What I haven't figured out yet is how to support resizing multiple images, since the %U only seems to contain the path to the first file. By using %f instead of %U it looks like the shell script is executed per selected file and it gets the path to each file individually.

0

Try writing an executable bash script to perform the operations you require and launch that from the contract, passing only the uri as a parameter.

Contractor does not expect the commandline to be complex - I suspect the problem is there somewhere.

So, if your script is called e.g. resize1200.sh then Exec=resize1200.sh -U%

After some experimentation the following simple script works for single files:

`#!/bin/bash io.elementary.terminal --execute="convert \"$1\" -resize '1200x1200' \"$1-test.jpg\""`

A more complex script based on this should work for multiple files and different output file naming (you need one --execute flag and each following command to run must be a single string - in quotes if it contains spaces -. Inside the string, parameters with spaces must be further quoted with escaped quotes.

7
  • Thanks for the tip! I've tried, see update above, but it doesn't seem to help. Commented Dec 5, 2017 at 11:57
  • OK, I'll try it out - but it might be worth putting the script into your home folder and making sure you have execute permissions. Also the script should run without user input using the supplied parameter Commented Dec 6, 2017 at 13:08
  • After some tests I think there might be a problem with the elementary terminal executing parameters which are scripts (although desktop apps seem to work OK). I'll raise an issue if there is not already one. Commented Dec 6, 2017 at 13:49
  • See amended answer above. Commented Dec 6, 2017 at 17:01
  • Thanks for your effort Jeremy, but this is quite a workaround, we're calling a sh scripts that calls the terminal with a script... And we still don't have a way to debug, I'll open an issue on debugging. I guess calling the terminal is a way to debug? It seems to work now, but I had to remove the - in front of the %U and replace io.elementary.terminal with pantheon-terminal (you're probably on the daily). Commented Dec 7, 2017 at 11:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.