Can't convert image file using a bash script

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Boogal
Posts: 8
Joined: 2018-11-11T18:52:05-07:00
Authentication code: 1152

Can't convert image file using a bash script

Post by Boogal » 2018-11-11T18:58:30-07:00

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

Code: Select all

test.sh filename.png 16
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.

User avatar
fmw42
Posts: 24139
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Can't convert image file using a bash script

Post by fmw42 » 2018-11-11T20:08:32-07:00

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

Code: Select all

bash test.sh lena.jpg 256
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

Boogal
Posts: 8
Joined: 2018-11-11T18:52:05-07:00
Authentication code: 1152

Re: Can't convert image file using a bash script

Post by Boogal » 2018-11-11T21:01:47-07:00

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.

User avatar
fmw42
Posts: 24139
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Can't convert image file using a bash script

Post by fmw42 » 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.

Boogal
Posts: 8
Joined: 2018-11-11T18:52:05-07:00
Authentication code: 1152

Re: Can't convert image file using a bash script

Post by Boogal » 2018-11-12T04:51:59-07:00

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.

snibgo
Posts: 10963
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Can't convert image file using a bash script

Post by snibgo » 2018-11-12T06:07:19-07:00

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:

Code: Select all

bash testpal.sh toes.png 32
... 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.
snibgo's IM pages: im.snibgo.com

Boogal
Posts: 8
Joined: 2018-11-11T18:52:05-07:00
Authentication code: 1152

Re: Can't convert image file using a bash script

Post by Boogal » 2018-11-12T13:55:48-07:00

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?

snibgo
Posts: 10963
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Can't convert image file using a bash script

Post by snibgo » 2018-11-12T14:05:08-07:00

Type "convert -version".
snibgo's IM pages: im.snibgo.com

Boogal
Posts: 8
Joined: 2018-11-11T18:52:05-07:00
Authentication code: 1152

Re: Can't convert image file using a bash script

Post by Boogal » 2018-11-12T14:25:11-07:00

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?

snibgo
Posts: 10963
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Can't convert image file using a bash script

Post by snibgo » 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?
snibgo's IM pages: im.snibgo.com

Boogal
Posts: 8
Joined: 2018-11-11T18:52:05-07:00
Authentication code: 1152

Re: Can't convert image file using a bash script

Post by Boogal » 2018-11-12T17:25:49-07:00

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.

User avatar
fmw42
Posts: 24139
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Can't convert image file using a bash script

Post by fmw42 » 2018-11-12T17:27:54-07:00

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}.

User avatar
fmw42
Posts: 24139
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Can't convert image file using a bash script

Post by fmw42 » 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?

Boogal
Posts: 8
Joined: 2018-11-11T18:52:05-07:00
Authentication code: 1152

Re: Can't convert image file using a bash script

Post by Boogal » 2018-11-12T18:15:21-07:00

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.

snibgo
Posts: 10963
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Can't convert image file using a bash script

Post by snibgo » 2018-11-12T18:32:56-07:00

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.
snibgo's IM pages: im.snibgo.com

Post Reply