gradients going wrong

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?".
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: gradients going wrong

Post by fmw42 »

Forgive me as i'm not that great with image magic. How do you decompose the colors of the image?
I am simply talking about convert hex to rgb. You can do that in IM. For example see my tidbits pages and particular at http://www.fmwconcepts.com/imagemagick/ ... php#colors

Or simply find any one of many online converters (by doing a google search for hex to rgb). For example,

http://www.yellowpipe.com/yis/tools/hex ... verter.php
http://www.colorcombo.com/bghex.html
http://www.translatum.gr/converter/hexadecimal.htm
http://www.string-functions.com/hex-rgb.aspx

So #ff0080 => rgb(255,0,128)

decompose the colors (hex components to rgb components) as
ff=>255, 00=>0, 80=>128,
then make three grayscale image using any of the following methods that works for you to generate each r,g,b component image:

(note gray### ranges from 0 to 100, but gray50 is for 8-bit value 127, the 8-bit gray corresponding to 128 is called fractal, see http://imagemagick.org/script/color.php)

convert -size 10x100 xc:white white.png (for red see -combine below)
convert -size 10x100 xc:black black.png (for green see -combine below)
convert -size 10x100 xc:fractal gray.png (for blue see -combine below)

or
convert -size 10x100 xc:gray100 white.png (for red see -combine below)
convert -size 10x100 xc:gray0 black.png (for green see -combine below)
convert -size 10x100 xc:fractal gray.png (for blue see -combine below)

or
convert -size 10x100 xc:"rgb(255,255,255)" white.png (for red see -combine below)
convert -size 10x100 xc:"rgb(0,0,0)" black.png (for green see -combine below)
convert -size 10x100 xc:"rgb(128,128,128)" gray.png (for blue see -combine below)


Then merge the 3 r,g,b channel images back into a single color RGB image:
convert white.png black.png gray.png -combine rgb.png
davidb2002
Posts: 37
Joined: 2008-09-01T08:31:26-07:00

Re: gradients going wrong

Post by davidb2002 »

What I don't understand from the method you describe is where the decompose comes back into play? I can easily 'decompose' the rgb with php to assign them to php values. But where do i Use these in the next IM commands?
convert -size 10x100 xc:white white.png (for red see -combine below)
convert -size 10x100 xc:black black.png (for green see -combine below)
convert -size 10x100 xc:fractal gray.png (for blue see -combine below)
None of the examples you provide appear to use the rgb components that we got previously (or maybe im missing something).
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: gradients going wrong

Post by fmw42 »

davidb2002 wrote:What I don't understand from the method you describe is where the decompose comes back into play? I can easily 'decompose' the rgb with php to assign them to php values. But where do i Use these in the next IM commands?
convert -size 10x100 xc:white white.png (for red see -combine below)
convert -size 10x100 xc:black black.png (for green see -combine below)
convert -size 10x100 xc:fractal gray.png (for blue see -combine below)
None of the examples you provide appear to use the rgb components that we got previously (or maybe im missing something).
Because I have converted the r,g,b components into grayscale color names.

The above is equivalent to

convert -size 10x100 xc:"rgb(255,255,255)" white.png (gray image for red component)
convert -size 10x100 xc:"rgb(0,0,0)" black.png (gray image for green component)
convert -size 10x100 xc:"rgb(128,128,128)" gray.png (gray image for blue component)


here each component color r=255, g=0 and b=128 is re-expressed as a proper IM grayscale value for that channel. Each channel is a grayscale image of gray value equivalent to the r or g or b decomposed value. Then each of the 3 gray channel images is recombined to form a proper rgb color image.

convert white.png black.png gray.png -combine rgb.png
davidb2002
Posts: 37
Joined: 2008-09-01T08:31:26-07:00

Re: gradients going wrong

Post by davidb2002 »

I think I understand now. Let me just make sure:

1. Decompose the Hex to RGB values:

Code: Select all

convert -size 1x1 xc:"#ffcc00" -format "rgb(%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)])" info:
returns: rgb(255,204,0)

2. Make 3 grayscale images using the decomposed rgb values supplied:

Code: Select all

convert -size 10x100 xc:"rgb(255,255,255)" red.png (this uses the red value)
convert -size 10x100 xc:"rgb(204,204,204)" green.png (this uses the green value)
convert -size 10x100 xc:"rgb(0,0,0)" blue.png (this uses the blue value)
3. Merge the 3 grayscale images into one:

Code: Select all

convert red.png green.png blue.png -combine result.png
Can you confirm that this is the correct procedure. I didn't relise before that you are using the 3 rgb values in the 3 separate converts in step 2.
davidb2002
Posts: 37
Joined: 2008-09-01T08:31:26-07:00

Re: gradients going wrong

Post by davidb2002 »

Ive tried what i have put in the above post and it doesn't completly work.

It appears to be fine for:

FFFFFF
CCCCCC

Heres the intersting part:

Neither version can do:
FF6600

6.3 can do:
C0C0C0
FF0080

6.2 can't.

In 6.3, using FF6600 and the above method produces a pinkish colour, when it should be orange. It's a very unsual situation. So here is my entire command procedure:

Code: Select all

/usr/local/bin/convert -size 60x52 plasma:fractal -virtual-pixel edge -blur 0x5 -shade 140x45 -normalize -size 1x100 xc:black -size 9x100 gradient: +append /media/usbdisk1/development/images/temp/1222077192.png

/usr/local/bin/convert -size 1x1 xc:"#FF0080" -format "rgb(%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)])" info:

convert \( -size 10x100 xc:"rgb(254,254,254)" \) \( size 10x100 xc:"rgb(0,0,0)" \) \( size 10x100 xc:"rgb127,127,127)" \) -combine /media/usbdisk1/development/images/default-components/gradients/gradient_temp.png

/usr/local/bin/convert /media/usbdisk1/development/images/temp/1222077192.png /media/usbdisk1/development/images/default-components/gradients/gradient_temp.png -fx 'v.p{0,u*v.h}' /media/usbdisk1/development/images/temp/1222077192.png
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: gradients going wrong

Post by fmw42 »

My guess is that the older versions of IM do not correctly convert the hex colors to rgb values. You may have to write your own conversion or go to one of the web sites, I referenced earlier to do the conversion. In fact, check the IM hex to rgb components for each color you have with one of those web sites and see if IM is converting it correctly. Then report back. You may have to create you own conversion of the hex colors either using another -fx escape calculation or rely upon the shell or an API to do that. In any case, reply back and let us know where the error is occurring.

Also you still seem to be using xc:"rgb(...)" and I thought you said that was not working. That was why I suggested you separate the colors into r,g,b components and build grayscale images from the grayscale names and then merge them. Please clarify.

P.S. Can't you upgrade to the latest IM version, where all this color conversion works correctly?

If you find that the conversion from hex to rgb is not correct using the method above
(convert -size 1x1 xc:"#FF0080" -format "rgb(%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)])" info:)
by comparing it to one of the html web site page calculators, then here is a rather long calculation using shell calculations. Someone may be able to make this more efficient:

hexval="#ff0080"
redh=${hexval:1:1}
redl=${hexval:2:1}
greenh=${hexval:3:1}
greenl=${hexval:4:1}
blueh=${hexval:5:1}
bluel=${hexval:6:1}
case $redh in
f|F) redh=15;;
e|D) redh=14;;
d|D) redh=13;;
c|C) redh=12;;
b|B) redh=11;;
a|A) redh=10;;
esac
case $redl in
f|F) redl=15;;
e|D) redl=14;;
d|D) redl=13;;
c|C) redl=12;;
b|B) redl=11;;
a|A) redl=10;;
esac
case $greenh in
f|F) greenh=15;;
e|D) greenh=14;;
d|D) greenh=13;;
c|C) greenh=12;;
b|B) greenh=11;;
a|A) greenh=10;;
esac
case $greenl in
f|F) greenl=15;;
e|D) greenl=14;;
d|D) greenl=13;;
c|C) greenl=12;;
b|B) greenl=11;;
a|A) greenl=10;;
esac
case $blueh in
f|F) blueh=15;;
e|D) blueh=14;;
d|D) blueh=13;;
c|C) blueh=12;;
b|B) blueh=11;;
a|A) blueh=10;;
esac
case $bluel in
f|F) bluel=15;;
e|D) bluel=14;;
d|D) bluel=13;;
c|C) bluel=12;;
b|B) bluel=11;;
a|A) bluel=10;;
esac
echo "redh=$redh; redl=$redl; greenh=$greenh; greenl=$greenl; blueh=$blueh; bluel=$bluel"
red=`convert xc: -format "%[fx: $redh * 16 + $redl]" info:`
green=`convert xc: -format "%[fx: $greenh * 16 + $greenl]" info:`
blue=`convert xc: -format "%[fx: $blueh * 16 + $bluel]" info:`
echo "$red,$green,$blue"


or you can avoid the use of -fx calculations, if that is where the issue lies, by using the following alternate, which makes use of the bc calculator:

hexval="#ff0080"
redh=${hexval:1:1}
redl=${hexval:2:1}
greenh=${hexval:3:1}
greenl=${hexval:4:1}
blueh=${hexval:5:1}
bluel=${hexval:6:1}
case $redh in
f|F) redh=15;;
e|D) redh=14;;
d|D) redh=13;;
c|C) redh=12;;
b|B) redh=11;;
a|A) redh=10;;
esac
case $redl in
f|F) redl=15;;
e|D) redl=14;;
d|D) redl=13;;
c|C) redl=12;;
b|B) redl=11;;
a|A) redl=10;;
esac
case $greenh in
f|F) greenh=15;;
e|D) greenh=14;;
d|D) greenh=13;;
c|C) greenh=12;;
b|B) greenh=11;;
a|A) greenh=10;;
esac
case $greenl in
f|F) greenl=15;;
e|D) greenl=14;;
d|D) greenl=13;;
c|C) greenl=12;;
b|B) greenl=11;;
a|A) greenl=10;;
esac
case $blueh in
f|F) blueh=15;;
e|D) blueh=14;;
d|D) blueh=13;;
c|C) blueh=12;;
b|B) blueh=11;;
a|A) blueh=10;;
esac
case $bluel in
f|F) bluel=15;;
e|D) bluel=14;;
d|D) bluel=13;;
c|C) bluel=12;;
b|B) bluel=11;;
a|A) bluel=10;;
esac
echo "redh=$redh; redl=$redl; greenh=$greenh; greenl=$greenl; blueh=$blueh; bluel=$bluel"
red=`echo "scale=0; $redh * 16 + $redl" | bc`
green=`echo "scale=0; $greenh * 16 + $greenl" | bc`
blue=`echo "scale=0; $blueh * 16 + $bluel" | bc`
echo "$red,$green,$blue"
davidb2002
Posts: 37
Joined: 2008-09-01T08:31:26-07:00

Re: gradients going wrong

Post by davidb2002 »

Hi,

Our Server Admin suggest that we don't do the upgrade as it would require an RPM install of it which is not built for the OS we are running.

How do you convert a hex value to the corresponding name like you mentioned?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: gradients going wrong

Post by fmw42 »

davidb2002 wrote:Hi,

Our Server Admin suggest that we don't do the upgrade as it would require an RPM install of it which is not built for the OS we are running.

How do you convert a hex value to the corresponding name like you mentioned?
Did you find out if the IM function was converting the hex values correctly as I asked? You need to know where the problem lies, before working out a solution. Please report back whether the IM function I suggested was converting the hex values correctly compared to the web sites that I sent you.

With regard to color names:

You have to convert first to get the r and g and b components in the range 0-255 and then you will have to build a lookup from that value in range 0-255 to the list of grayvalue names in the IM list of colornames (but map each value in the range of 0-255 to only one grayname as sometimes there are two graynames that are equivalent.

I have given you a function to convert the hex values to r, g, b components.

See:

http://imagemagick.org/script/color.php

Build a file lookup.txt with two columns. One column is the color value in range 0-255 and the next column (space or comma separated) is the grayname.

Then you will have to build a shell function to search the file and find the grayname given a value

But you also need to test that you can do it correctly even using the colornames. You need to manually convert one of the hex values that is giving you trouble to r,g,b components in the range 0-255, then look at the color name page, find the correct name, then build your color patch image and see if that all works.

P.S. In looking at the page for color names above, I see that not every gray value is represented by a name. Therefore this may not be an adequate solution for you.

However, I reiterate, that you need to identify where the problem really lies. Take your system with the oldest IM version on it and do the following where you reported that #FF6600 gave the wrong value:

1) convert -size 1x1 xc:"#FF6600" -format "rgb(%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)])" info:

This should report: rgb(255,102,0)

Let us know what you get.

2) convert -size 1x1 xc:"#FF6600" -depth 8 txt:

This should report:

# ImageMagick pixel enumeration: 1,1,255,rgb
0,0: (255,102, 0) #FF6600 rgb(255,102,0)

Possibly the left or right side values may not be showing (255,102,0)

Let us know what you get.

3) convert -size 100x100 xc:"rgb(255,102,0)" test_color.png
Image

4) identify -verbose test_color.png

This should report:
Channel statistics:
red:
min: 15 (1)
max: 15 (1)
mean: 15 (1)
standard deviation: -0 (-0)
green:
min: 6 (0.4)
max: 6 (0.4)
mean: 6 (0.4)
standard deviation: -0 (-0)
blue:
min: 0 (0)
max: 0 (0)
mean: 0 (0)
standard deviation: -0 (-0)
Histogram:
10000: (65535,26214, 0) #FFFF66660000 rgb(255,102,0)

Let us know what you get for all the above. NOTE: the unnormalized values of 15,6,0 may not be correctly reported. This appears to be a bug in the current version as I would expect on Q16 IM to get 65535,26214,0. However, the normalized values in parentheses are correct as 1,0.4,0

5) convert -size 100x100 xc:"#FF6600" test_color_hex.png
Image

6) identify -verbose test_color_hex.png

This should return:
Channel statistics:
red:
min: 15 (1)
max: 15 (1)
mean: 15 (1)
standard deviation: -0 (-0)
green:
min: 6 (0.4)
max: 6 (0.4)
mean: 6 (0.4)
standard deviation: -0 (-0)
blue:
min: 0 (0)
max: 0 (0)
mean: 0 (0)
standard deviation: -0 (-0)
Histogram:
10000: (65535,26214, 0) #FFFF66660000 rgb(255,102,0)

Let us know what you get for all the above.

7) convert -size 100x100 xc:"#FF6600" -colorspace rgb test_color_hex2.png
Image

\8) identify -verbose test_color_hex2.png

This should return:
Channel statistics:
red:
min: 15 (1)
max: 15 (1)
mean: 15 (1)
standard deviation: -0 (-0)
green:
min: 6 (0.4)
max: 6 (0.4)
mean: 6 (0.4)
standard deviation: -0 (-0)
blue:
min: 0 (0)
max: 0 (0)
mean: 0 (0)
standard deviation: -0 (-0)
Histogram:
10000: (65535,26214, 0) #FFFF66660000 rgb(255,102,0)

Let us know what you get for all the above.

9) 255 is gray name white; 102 is gray name gray40; 0 is gray name black

So try

convert -size 100x100 xc:white xc:gray40 xc:black -combine test_color3.png
Image

10) identify -verbose test_color3.png

This should return:
Channel statistics:
red:
min: 15 (1)
max: 15 (1)
mean: 15 (1)
standard deviation: -0 (-0)
green:
min: 6 (0.4)
max: 6 (0.4)
mean: 6 (0.4)
standard deviation: -0 (-0)
blue:
min: 0 (0)
max: 0 (0)
mean: 0 (0)
standard deviation: -0 (-0)
Histogram:
10000: (65535,26214, 0) #FFFF66660000 rgb(255,102,0)

Let us know what you get for all the above.


By the way, are you running Q16 or Q8 IM?
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: gradients going wrong

Post by anthony »

davidb2002 wrote:Hi,

Our Server Admin suggest that we don't do the upgrade as it would require an RPM install of it which is not built for the OS we are running.

How do you convert a hex value to the corresponding name like you mentioned?
From a SVN or source download of IM you can generate RPM packages. This is what I do for my own machine (Fedora 8)...

First edit "ImageMagick.spec.in" and add any specific configuration options you want/need to that file.

Now configure (no special configuration options is needed here, and will not get applied to the final installabel package.

Code: Select all

rm config.status config.log
nice ./configure
Create the Source RPM (and cleanup)

Code: Select all

make srpm
chmod -R u+w ImageMagick-*[0-9]
rm -rf ImageMagick-*[0-9]{,.tar.bz2}
Now you have packaged the source into a SRPM, you can build it from that file. You don't even need ROOT privileges for this!

Code: Select all

tmp=/tmp/build-using-a-long-build-path; rm -rf $tmp; mkdir $tmp
nice rpmbuild --define="_sourcedir $tmp" --define="_specdir $tmp" \
              --define="_rpmdir $tmp" --define="_builddir $tmp" \
              --nodeps --rebuild    ImageMagick-*.src.rpm
ls -Fla $tmp/*/ImageMagick-[6p]*.i386.rpm
rm -f *.i386.rpm; cp $tmp/*/ImageMagick-[6p]*.i386.rpm .
rm -rf $tmp
You now have not only a source package, but the pre-build RPM package that was built and configured for the machine you built it on!

You can install it (this needs ROOT previlages) with

Code: Select all

sudo rpm -Uhv --force --nodeps ImageMagick-[6p]*.i386.rpm
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
davidb2002
Posts: 37
Joined: 2008-09-01T08:31:26-07:00

Re: gradients going wrong

Post by davidb2002 »

Just checked to see whats happening with converting hex to rgb, and it coming back blank regardless of the hex:

/usr/local/bin/convert -size 1x1 xc:"#000000" -format "rgb(%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)])" info:
#000000 -> rgb(,,)

/usr/local/bin/convert -size 1x1 xc:"#ffffff" -format "rgb(%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)])" info:
#ffffff -> rgb(,,)

/usr/local/bin/convert -size 1x1 xc:"#ffcc00" -format "rgb(%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)])" info:
#ffcc00 -> rgb(,,)

So there may be my problem.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: gradients going wrong

Post by fmw42 »

davidb2002 wrote:Just checked to see whats happening with converting hex to rgb, and it coming back blank regardless of the hex:

/usr/local/bin/convert -size 1x1 xc:"#000000" -format "rgb(%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)])" info:
#000000 -> rgb(,,)

/usr/local/bin/convert -size 1x1 xc:"#ffffff" -format "rgb(%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)])" info:
#ffffff -> rgb(,,)

/usr/local/bin/convert -size 1x1 xc:"#ffcc00" -format "rgb(%[fx:floor(255*r)],%[fx:floor(255*g)],%[fx:floor(255*b)])" info:
#ffcc00 -> rgb(,,)

So there may be my problem.

But did you try my other method in 2)

convert -size 1x1 xc:"#FF6600" -depth 8 txt:

What does this return? If this works, then I can show you how to extract the r,g,b colors from it.

Truly, you would be better off following Anthony's suggestions about how to upgrade your version of IM. Show his notes to your ISP and get them to do it.
davidb2002
Posts: 37
Joined: 2008-09-01T08:31:26-07:00

Re: gradients going wrong

Post by davidb2002 »

Ok, here is what I get :

/usr/local/bin/convert -size 1x1 xc:"#ffcc00" -depth 8 txt:
#ffcc00 -> 0,0: (255,204, 0) #FFCC00
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: gradients going wrong

Post by fmw42 »

davidb2002 wrote:Ok, here is what I get :

/usr/local/bin/convert -size 1x1 xc:"#ffcc00" -depth 8 txt:
#ffcc00 -> 0,0: (255,204, 0) #FFCC00
Well, that seems to come out correctly for rgb = 255,204,0.

But I asked about the one that you said you did not get to work the other way, namely,

convert -size 1x1 xc:"#FF6600" -depth 8 txt:

note 66 not CC

That was the one you reported above did not work out. Does this method give you the right rgb values? It should report

convert -size 1x1 xc:"#FF6600" -depth 8 txt:
# ImageMagick pixel enumeration: 1,1,255,rgb
0,0: (255,102, 0) #FF6600 rgb(255,102,0)

If this works, then we can extract the r,g,b values of 255, 102 and 0 and create a lookup table of names if you cannot use xc:"rgb(255,102,0) to get the color you want.

Let me know what you get for the above. The we can try to proceed from there.

Also tell me if the following gives you the correct color:

convert -size 100x100 xc:"rgb(255,102,0)" -depth 8 test_color.png

Image
davidb2002
Posts: 37
Joined: 2008-09-01T08:31:26-07:00

Re: gradients going wrong

Post by davidb2002 »

convert -size 1x1 xc:"#FF6600" -depth 8 txt:

note 66 not CC

That was the one you reported above did not work out. Does this method give you the right rgb values? It should report
yes give me the exact same as you reported
Also tell me if the following gives you the correct color:

convert -size 100x100 xc:"rgb(255,102,0)" -depth 8 test_color.png
On my local copy (the later verion), it does render the correct image. On the older version it renders the correct colour, but with inconsistent black bars.

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

Re: gradients going wrong

Post by fmw42 »

Also tell me if the following gives you the correct color:

convert -size 100x100 xc:"rgb(255,102,0)" -depth 8 test_color.png
On my local copy (the later verion), it does render the correct image. On the older version it renders the correct colour, but with inconsistent black bars.

Image
Your image looks fine to me. I see no black bars! Are you sure you are not having trouble with your browser or other image viewer? What are you using to view it? Is there any chance your IM installs are corrupted in some way?

If there is really a problem, then, we can proceed with some lookup table to generate the results.

First tell me if this works:
convert -size 100x100 xc:white xc:gray40 xc:black -combine test_color4.png
Image
Post Reply