Page 1 of 1

Interpolated lookup gradients with colour weighting

Posted: 2013-04-10T07:04:22-07:00
by PeterUK
Hi,

I've read a few topics like this:
viewtopic.php?f=1&t=19812

And while that one does have a solution at the bottom, it's not really what I'm looking for. The colours sort of fade into eachother because of the method used and it is not a real gradient. Now I can have ImageMagick create a gradient with interpolated lookup and it is perfect, it even matches Photoshop's gradient identically to the naked eye, so long as the colour spacing is even, but what I really need to be able to do is weight the colours like you can in Photoshop's (and others) gradient creator. I know this isn't natively supported by ImageMagick as I have read the docs on it and they say that. I was just wondering if anyone has a good method to do this that they would be willing to share?

I will not know the weightings in advance (so I am not looking to setup a specific set of weightings, I want to be able to decide them on the fly). I have tried creating multiple 2 colour gradients with interpolation and piecing them together, this comes out noticeably different and not as pleasing to the eye as Photoshop, in fact it comes out identically to if I actually create the gradients myself using PHP GD.

Any help would be much appreciated!

Re: Interpolated lookup gradients with colour weighting

Posted: 2013-04-10T17:25:53-07:00
by anthony
IM does have controls to define how the gradient should be interpolated.
http://www.imagemagick.org/Usage/color_mods/#clut

But this is only useful for regular spacing of the 'color stops'.

I can see only few ways to prevent color fading.
1/ generate each color stop to color stop as a separate gradient,
2/ generate a mathematical function for each R,G,B (or whatever colorspace) channel across the color spots.

The first will generally produce sharp 'saw-tooth' like gradients, and though this can be smoothed, smoothing will probably cause the 'stop color' to become off-color.

The second can be done in a number of ways. Fred I believe has a gradient generator that uses splines.
Another is to use polynomal function curve fitting. For example see...
http://www.imagemagick.org/Usage/color_mods/#curves

That example is only for a single black and white gradient. It would need to be done for each of the 3 channels
(for whatever colorspace you want to generate the gradient in). However be warned that it can 'overshoot'
the 'stop' making it appear the stop has 'shifted'.




ASIDE: I have not mentioned using Shepard's Interpolation (whcih was mentioned in the pointed to topic), as that method is leaky, in that colors drift toward the 'average' color of the stops as you move way from any specific color spot. The alternative to shepards, using true 'Diffusion' will, in the 1-dimensional case, degenerate into linear gradient segments. These sparse interpolations only work well for hight dimensions.

Re: Interpolated lookup gradients with colour weighting

Posted: 2013-04-10T17:54:10-07:00
by PeterUK
Thanks very much for your reply.

I have already tried method 1 and you are exactly correct, it produces these saw-tooth type gradients. This is also the same when I generate my own gradient using PHP GD. This is actually my first time using ImageMagick at all (just today) and I find the documentation (and the flexibility of it) quite overwhelming. Could you point me in the right direction of how to smooth the gradient parts of the image after piecing together the multiple gradients?

Right now I have written a custom script for PHP GD which forces a certain percentage of the gradient area to be "larger" and therefore reduces the "saw-tooth" effect, but I have to apply a lot of blur afterwards to get rid of the banding. If ImageMagick could do the smoothing instead I would like to compare the results.

Cheers!

Re: Interpolated lookup gradients with colour weighting

Posted: 2013-04-10T18:14:27-07:00
by anthony
PeterUK wrote:Could you point me in the right direction of how to smooth the gradient parts of the image after piecing together the multiple gradients?
just use -blur on the saw-tooth image.
http://www.imagemagick.org/Usage/blur/

Right now I have written a custom script for PHP GD which forces a certain percentage of the gradient area to be "larger" and therefore reduces the "saw-tooth" effect, but I have to apply a lot of blur afterwards to get rid of the banding. If ImageMagick could do the smoothing instead I would like to compare the results.



The alternative to generating a simple piece-wise 'linear gradient' between points is to use a curved gradient.
The simplist technique is actually very wierd... generate a 2 pixel image of the two colors, then
Resize that image using 'Gaussian-like Filter'

Resized Gradient
http://www.imagemagick.org/Usage/canvas ... ent_resize

But again you need to do this for each segment.

The problem with this 'piece-wise' method when the color stop is already part of the gradient and you are just wanting to refine the shape. For example with color-stop sequence like white-grey-black you end up with a 'plateau' like effect at the 'grey' color-stop, rather than a continuous slope going through the grey color-stop.



What you really want is a plateau at 'peak' color-stops, and 'continuous slopes' at non-peak color-stops.
That is actually more of a piecewise 'spline interpolation' type gradient.

Really a 1-D 'sparse-gradient' generator really should be added to IM, (and specifically to -draw which really needs it).

Re: Interpolated lookup gradients with colour weighting

Posted: 2013-04-12T07:11:26-07:00
by PeterUK
Thanks for the links there.

Here are some comparison images with descriptions.

So this is the original Photoshop image, the gradient proportions are like so (in PHP array format since it's easily readable and what I've been using), where the array keys are percentages:

Code: Select all

$colours = array(
    5   =>  array(249, 230, 0),
    35  =>  array(111, 21, 108),
    65  =>  array(253, 124, 0),
    95  =>  array(0, 40, 116)
);
Now this is an evenly proportioned gradient, which ImageMagick is perfectly capable of doing using interpolated lookup, but it is a good test gradient because of the colours used in it. Most of the gradients I will need to produce will not be evenly spaced like this.

Here is Photoshop's original gradient image:
Image

Now here is ImageMagick's attempt using interpolated lookup:
Image
This is ultimately a very good result, so it's a real shame we can't use this method for different colour spacing.

Here is ImageMagick with each gradient generated separately then pieced together (left), next to my attempt to do the same thing in PHP GD (right)
ImageImage
As you can see apparently we were using the same method because these are identical.

Now here's the same 2 images with ImageMagick's blur applied (0x8) (left), and PHP GD's gaussian blur applied (15x) (right):
ImageImage
We can see ImageMagick's blurring is far superior (I struggle to get a similar effect on PHP GD), and it has certainly made the image closer to the original (especially the purple band of the image which appeared very thin).

Now here's my modified PHP GD script which forces colour bands to have more presence:
Image
Banding is clearly visible, so with some PHP GD blur applied:
Image
The banding is still visible although it is much reduced from before. Finally here is the PHP GD modified version with ImageMagick's blur:
Image

I personally feel the combination of my custom PHP GD script plus ImageMagick's blur (final image) creates the gradient most similar to Photoshop's original so it looks like for best results I will need to use a combination of the two, although I welcome any opinons. :)

Re: Interpolated lookup gradients with colour weighting

Posted: 2013-04-14T21:51:33-07:00
by anthony
As mentioned before Fred has a script "curves" that generates spline curves from a set of points to generate gradients using irregularly generated 'stops'.
http://www.fmwconcepts.com/imagemagick/curves/index.php

If this is applied to a linear grayscale image you get a linear gradient of that curve.

A color gradient is simply 3 grayscale gradients combined together.

I am certain he can throw together a script that could generate a 1D gradient from color points.

Re: Interpolated lookup gradients with colour weighting

Posted: 2013-04-14T23:24:50-07:00
by fmw42
anthony wrote:As mentioned before Fred has a script "curves" that generates spline curves from a set of points to generate gradients using irregularly generated 'stops'.
http://www.fmwconcepts.com/imagemagick/curves/index.php

If this is applied to a linear grayscale image you get a linear gradient of that curve.

A color gradient is simply 3 grayscale gradients combined together.

I am certain he can throw together a script that could generate a 1D gradient from color points.
This is something I thought about some time ago when I first saw that documented in CSS. But it has been on a back burner for a while.

Re: Interpolated lookup gradients with colour weighting

Posted: 2013-04-15T11:12:17-07:00
by PeterUK
Unfortunately I don't really have the luxury of using the scripts as my code needs to work through PHP without exec().

I would appreciate some help with this though:
viewtopic.php?f=10&t=23180

Re: Interpolated lookup gradients with colour weighting

Posted: 2013-05-14T16:58:09-07:00
by fmw42
I have created a new bash shell script to create CSS-like linear or radial gradients with 2 or more color stops. It is called multigradient and can be obtained from my web site link below.

For the OP of this topic, you might be able to pull the pieces out of my script and build it into an Imagick or Magickwand for PHP script or some other API such as Perlmagick.