Page 1 of 2
Can't convert image file using a bash script
Posted: 2018-11-11T18:58:30-07:00
by Boogal
I'm trying to make a .sh file for use in cygwin to automate something I find myself doing a lot. The file, test.sh, contains the following:
Code: Select all
#!/bin/bash
VAR=$(convert $1 -colors $2 -depth 8 -format "%c" histogram:info: | sort -r -k 1 | head -n 16 | grep -o -E "\#.{0,6}" | sed "s/#/xc:#/g" | sed ':a;N;$!ba;s/\n/ /g')
convert -size 60X60 $VAR +append ${1::-4}palette.png
The file has both +w and +x access in cygwin, however if I type
I get the following error:
Code: Select all
convert: no encode delegate for this image format `XC' @ error/constitute.c/WriteImage/1240.
However if I enter both of these lines by themselves into cygwin, the process produces the correct file I need just fine. I just downloaded cygwin today and installed imagemagick through that installer, so I assume I have the latest version. What am I doing wrong? The only difference I can see is in passing the argument to the function within the script.sh file, is that what's going wrong? How can I fix it?
I appreciate any help, as I've been stumped on this for a few hours now.
Re: Can't convert image file using a bash script
Posted: 2018-11-11T20:08:32-07:00
by fmw42
What are your $1 and $2 argument values?
On my Mac, I can run your two commands as:
Code: Select all
VAR=$(convert lena.jpg -colors 256 -depth 8 -format "%c" histogram:info: | sort -r -k 1 | head -n 16 | grep -o -E "\#.{0,6}" | sed "s/#/xc:#/g" | sed ':a;N;$!ba;s/\n/ /g')
convert -size 60X60 $VAR +append ${1::-4}palette.png
and it produces a "palette.png" image. But I do not know what to expect from ${1::-4} and
there is no sign of that in the output filename.
But when I insert the variables $1 and $2 in a bash script, it fails also.
Code: Select all
#!/bin/bash
VAR=$(convert $1 -colors $2 -depth 8 -format "%c" histogram:info: | sort -r -k 1 | head -n 16 | grep -o -E "\#.{0,6}" | sed "s/#/xc:#/g" | sed ':a;N;$!ba;s/\n/ /g')
convert -size 60X60 $VAR +append ${1::-4}palette.png
test.sh: line 3: -4: substring expression < 0
I think it does not like your ${1::-4}
But I am not that expert enough to tell you why. I don't understand ${1::-4}.
The script works fine if I remove ${1::-4}.
Perhaps it is confusing the ${1::-4} with your shell $1 and $2 arguments and not expecting -4
P.S. If you do not want your image to produce dithered colors, then add +dither before -colors X
Re: Can't convert image file using a bash script
Posted: 2018-11-11T21:01:47-07:00
by Boogal
The ${1::-4} was just to produce an output filename that was the same as the input filename but with "palette" tagged on to the end. It's not that important to the overall thing, but I get the same error when I remove it.
The $1 and $2 argument values are the filename of the image whose palette I'm trying to get, and $2 is the number of colors I'd like the palette to contain.
edit: Even if I replace the $1 and $2 in the file with a static filename and color number, the script still gives me the same error.
Code: Select all
convert: no encode delegate for this image format `XC' @ error/constitute.c/WriteImage/1240.
Re: Can't convert image file using a bash script
Posted: 2018-11-11T23:24:27-07:00
by fmw42
That is odd. Normally, one would put quotes about the hex value xc:'#XXXXXX'. But I think that is not necessary when in the string variable you craated ($VAR), since it worked fine for me. An alternate for xc: is canvas:
To get the name of the image for prefixing the output, you can create a new variable as:
name=$(convert image -format "%t" info:)
Then use ${name}_palette.png.
Re: Can't convert image file using a bash script
Posted: 2018-11-12T04:51:59-07:00
by Boogal
fmw42 wrote: ↑2018-11-11T23:24:27-07:00
That is odd. Normally, one would put quotes about the hex value xc:'#XXXXXX'. But I think that is not necessary when in the string variable you craated ($VAR), since it worked fine for me. An alternate for xc: is canvas:
To get the name of the image for prefixing the output, you can create a new variable as:
name=$(convert image -format "%t" info:)
Then use ${name}_palette.png.
If I change xc to canvas in the script I get:
Code: Select all
convert: no encode delegate for this image format `CANVAS' @ error/constitute.c/WriteImage/1240.
It feels like it has to be a permissions thing or something at this point, because again if I just manually do the things the script does I don't get any error. I have other script files that work just fine though.
Re: Can't convert image file using a bash script
Posted: 2018-11-12T06:07:19-07:00
by snibgo
What version of IM?
man bash says I can use "${parameter:offset:length}" with negative length meaning offset from the end. So "${1::-4}" would be the first parameter, without the final 4 characters (eg "toes.png" makes "toes").
On my Windows 8.1 with Cygwin, naming the OP script as "testpal.sh", running the command:
... creates the file "toespalette.png".
Inserting "echo $VAR" in the middle, we get:
Code: Select all
xc:#586A4E xc:#967889 xc:#AA8E8C xc:#778666 xc:#737468 xc:#6A6E56 xc:#8F8B73 xc:
#AEA69F xc:#916C65 xc:#715A67 xc:#ECC5B8 xc:#D1AAA1 xc:#C1927D xc:#8D7571 xc:#54
3847 xc:#BDC0BF
... which seems reasonable.
I would add "+repage" after the "+append".
I would also use v7 "magick", not "convert" unless you have v6.
Re: Can't convert image file using a bash script
Posted: 2018-11-12T13:55:48-07:00
by Boogal
snibgo wrote: ↑2018-11-12T06:07:19-07:00
What version of IM?
I'm not sure which version I have, it just came bundled with cygwin. Is there a way I can check?
Re: Can't convert image file using a bash script
Posted: 2018-11-12T14:05:08-07:00
by snibgo
Type "convert -version".
Re: Can't convert image file using a bash script
Posted: 2018-11-12T14:25:11-07:00
by Boogal
snibgo wrote: ↑2018-11-12T14:05:08-07:00
Type "convert -version".
Version: ImageMagick 6.9.10-11 Q16 x86_64 2018-09-08
So maybe my version not being up to date is causing it?
Re: Can't convert image file using a bash script
Posted: 2018-11-12T15:15:55-07:00
by snibgo
That version should be fine.
Does the script always fail, or only with certain inputs? What does "echo $VAR" say?
Re: Can't convert image file using a bash script
Posted: 2018-11-12T17:25:49-07:00
by Boogal
snibgo wrote: ↑2018-11-12T15:15:55-07:00
That version should be fine.
Does the script always fail, or only with certain inputs? What does "echo $VAR" say?
If I run the script, it fails every time. I've tried a few different images and color numbers, but I always get the same error. If I run "echo $VAR" afterwards, it shows as blank, I assume because it's only defined within the scope of that file. If I add a "echo $VAR" after the first line in the script file, it shows the correct variable, so the last line has to be what's failing.
Re: Can't convert image file using a bash script
Posted: 2018-11-12T17:27:54-07:00
by fmw42
snibgo, perhaps different Unix systems have trouble with the ${1::-4} syntax. It does not work in a bash script on my Mac and give an error as I mentioned above. In my Mac terminal, the two command lines when pasted work without error, but nothing is added for the ${1::-4}.
Re: Can't convert image file using a bash script
Posted: 2018-11-12T17:31:22-07:00
by fmw42
Try using var and $var rather than VAR and $VAR. Perhaps your Unix thinks all cap variables are environment variables or bash reserved variables. Does that make a difference?
Re: Can't convert image file using a bash script
Posted: 2018-11-12T18:15:21-07:00
by Boogal
fmw42 wrote: ↑2018-11-12T17:31:22-07:00
Try using var and $var rather than VAR and $VAR. Perhaps your Unix thinks all cap variables are environment variables or bash reserved variables. Does that make a difference?
No change.
Re: Can't convert image file using a bash script
Posted: 2018-11-12T18:32:56-07:00
by snibgo
As Fred says, remove "${1::-4}" for now.
Do you have other bash scripts? Do they work?
If "echo $VAR" works before the convert, then that is probably okay, but may have a spurious carriage-return at the end.
How did you create the shell script file? If you used Windows tools, line-ends are probably marked with carriage-return and line-feed, but bash normally expects just line-feed, and you need to tell it to ignore carriage-return. See
IM with Cygwin: Line ends for workarounds. Personally, I use the SHELLOPTS environment variable.