PDA

View Full Version : How can I do a limited/masked gradient fill in GIMP?



Thurlor
05-07-2011, 11:02 PM
Lately I've been messing around with GIMP, trying out new techniques as I come across them. Anyways, I'm probably just overlooking this feature, but is there a way in which I can do a 'shape based' gradient fill that plateus at a certain value and shape. Another way of wording it would be; can GIMP blend between 2 different coloured shapes (one atop the other) resulting in a gradient between the two?

Here is an example of what I mean. Just a very simple image with one shape on top of another.

35600

I've had a look at the 'interpolate' function of Inksacpe, but it requires each shape to have the same number of nodes and results in intermediate steps being smaller than the final image.

Anyways, thanks in advance.

Ghostman
05-08-2011, 04:33 AM
I'm not entirely sure what you're trying to achieve. Is the black-colored area in your example image supposed to be where the gradient would be? So there'd be gradient going from the outer edge of the area to it's inner edge?

Thurlor
05-08-2011, 06:01 AM
So there'd be gradient going from the outer edge of the area to it's inner edge?

Yes, that's exactly what I want. I couldn't really show it with that image, but it's supposed to be a gradient going from black to white, with the surrounding area also black. I hope that makes sense.

Ghostman
05-08-2011, 06:33 AM
I don't think there's any easy way to do this in GIMP. There are ways (blurs, bevels) to create a black to white gradient to surround the inner area, but these would all result in the gradient being of equal thickness in all directions. That is, it would match the shape of the inner edge but not the outer one.

Although perhaps you could create two gradient masks, one based on the inner edge and the other one on the outer edge, and combine them by setting blend mode to multiply.

Ghostman
05-08-2011, 03:38 PM
I toyed a bit with that example pic and came up with this method for creating something like the effect you're after. Unfortunately the shapes of the inner and outer edges of the gradient zone are not preserved 100% accurately, but you do get a fait approximation of them.

First, you'll need to create two layers, one for working on the inner edge of the gradient, and another for working on the outer edge. Notice how I've inverted the black & white for these:
3561635617

Let's edit the layer that contains only the inner shape first. Select the WHITE area and apply a Gaussian Blur (I used 120 pixel width) on it:
35618
This will create a gradient that smoothly darkes around the inner edge, yet maintains it's shape. Note, however, that the gradient only goes from white to gray, NOT white to black.

To fix this issue, make copies of the layer and set their blend modes to "multiply", then merge them. The result will be a single layer that contains a gradient from white to black, but without messing up the shape too much. You'll likely see a better quality result if instead of copying the same blurred layer, you create each layer manually and use a different Gaussian Blur width for each. Once you've merged the layers, invert the colors:
35619

Ghostman
05-08-2011, 03:47 PM
As for the outer edge, just use the same kind of process, but without inverting colors at the end:
35620
35621
35622

Now you should have two gradient layers, one for the inner edge and one for the outer edge. Place them so that the INNER shape gradient is above the OUTER one. Set this topmost layer's blend mode to "multiply" and set it's opacity to 50%. This should result in the final gradient band, limited by the designated shapes of the inner and outer edges, though not quite perfectly:
35623

You can merge the inner and outer gradient layers to get a single layer containing this final gradient, which can then be used for a mask.

I hope this advice was of any use to you :)

Thurlor
05-08-2011, 07:52 PM
@Ghostman

Thanks muchly for the detailed reply. It's definitely something I will have to try. I think I'm currently onto something using Wilbur as well, though I haven't had a chance to check it out properly yet.

Anyways, the use for all of this will be to set gradients below and above 'sea level' with upper and lower contour guides, whilst maintain the original shape of the landform. I can't think of a better way to explain what I'm after. If I'm going about this completely wrong and there is some easier way to accomplish my goal, I can't see it..

RobA
05-09-2011, 04:21 PM
There was a discussion on this back in '07
http://www.cartographersguild.com/showthread.php?1224-Reverse-Quantizing-AKA-how-to-get-a-heightfield-from-contour-lines

Might be something there that helps.

-Rob A>

sambrookjm
05-19-2011, 05:38 PM
Would this GIMP script be useful? To use it, you need to have your shape as the only non-alpha portion of the GIMP image. This script converts the image to a square, does a rectangular-to-polar conversion, and does a linear gradient down each column along the non-transparent portions of the drawing before going back to rectangular coordinates. It can also do contours, if you so desire. The script will show up in the Filters/SambrookJM menu under GIMP.

It's not perfect, but it could be a good starting point. It's not a fast script at all, so any ideas on how to speed things up would be greatly appreciated. I'd also like to know how you delete the selection-mask channel, since the ways I've tried haven't worked.

Hope this helps out somewhat...

Thurlor
05-19-2011, 07:20 PM
@sambrookjm: Thank you muchly for that. I'll be having a close look at it in the next few hours and I'll let you know how it works out.

RobA
05-19-2011, 10:53 PM
This is the best I could do with inkscape.

I duplicated the inner shape after tracing the bitmap, then dragged out each node to its respective location on the larger shape so all the node counts and orientations matched.
35930

This was a 30 item interpolate, with a 0.5% blur applied to smooth it out.

-Rob A>

Thurlor
05-20-2011, 09:07 PM
@sambrookjm: Unfortunately I think I am doing something wrong as your script just makes a large circular gadient centred in my image.

@RobA: That is actually the approach I have been working on, but I am none to keen about fiddling with the nodes as Inkscape has a tnedency to crash when I start working on things like that. The other thing I noticed is that I would need to create a 'mid-way' guide contour if one of my shapes is especially complex. In the test image I provided the inner shape has a curved 'indent' that needs to be guided to the outer shape, else one gets high contrast edges/ridges forming. I hope that makes sense.

Recently I have been looking into using Wilbur. I just wish Wilbur allowed the use of layers, so far I've been exporting as greyscale bmp's and combining them in Gimp as layers.

Anyways, back to it for me.

sambrookjm
05-21-2011, 06:46 AM
@sambrookjm: Unfortunately I think I am doing something wrong as your script just makes a large circular gadient centred in my image.

Try making the white part transparent (color to alpha). That way, you'll only get the shape to have the gradient.

If you make the white background transparent, it will look like ths:

35948

As I said, it's not a perfect script, but it is a starting point. Maybe a select by color instead of a select by alpha would be better?

Thurlor
05-21-2011, 09:48 PM
@sambrookjm: Now I see where I was going wrong. After the month winds down and I'm not messing with a challenge entry I'll look into again.

sambrookjm
05-24-2011, 05:46 PM
@sambrookjm: Now I see where I was going wrong. After the month winds down and I'm not messing with a challenge entry I'll look into again.

There were a couple of errors in the first version of the script, mainly when the layers weren't the same size as the image. I've fixed that, and also given the choice of either doing the entire alpha channel of the layer, or just selecting a specifc color. Use this new version of the script when you get around to it.

36036

Thurlor
05-24-2011, 05:53 PM
@sambrookjm: Once again thank you.