5

I have a recurring problem that I'd like to solve once and for all: how to create a blurry vector image.

For example, this bitmapped image represents the drop shadow for a rectangle:

nice bitmapped blur

It should be possible, with 50 or so rectangles with rounded corners, to represent it pretty well in an SVG or Illustrator file.

The main problems are that:

  1. blends use a linear distribution of gray levels, so the edges don't fade out correctly
  2. image tracing fails to recognize the smooth nature of the image and adds thousands of points, resulting in a large and jaggy image

I am looking for some way to create the correct distribution of gray levels while retaining the blurry effect.

This is just a simple example, but I often need blurred images that are much more complex.

I can either start with a sharp-edged object or I can create the "first and last" paths manually and blend between them. The problem there is having the correct levels.

This is what a 50-path blend looks like:

enter image description here

the transitions from gray and to white are much too abrupt.

Does anyone know how to create paths to better represent fuzzy content?

At this point, it's such an issue that I'd be happy to use an entirely new app for this single task.

[edit] I know about the SVG blur effect, but it won't work for my purposes. One of my main use cases is creating images in Mac apps, and SVG filters are ignored. For web use, I have also found that zooming a page causes the SVG filter to scale incorrectly.

3
  • Options are either rasterized effects or gradient mehes. Both of which have downsides. Meshes would be great alas they arent widely supported and pain to make. There is really no good solution for this – joojaa Feb 17 at 15:36
  • Sort of a reverse of this: graphicdesign.stackexchange.com/questions/121565/… – Scott Feb 17 at 18:29
  • Formats have restrictions. I think it's an uphill battle to overcome format restrictions for some specific appearance... much they same way trying to remove all indicators of pixels in raster artwork is an uphill, if not insurmountable, battle. One is left with the choice... appearance or format, not both. – Scott Feb 23 at 18:37
5
+150

Let me explore the topic a bit.

The shape

If we are attempting to do this with vector shapes, the shape itself must be right. It is easy to have deformed or disproportional shapes.

enter image description here

One way to prepare them is duplicating the overall shape and using the contour lines thicker on the shape it will be the final border of the shadow.

enter image description here

Now we have 2 shapes to blend. They should have the same amount of nodes.

The blending or morphing

Normally one tool available on vector design software is blending (or morphing) for shapes. The simplest method will make a linear blending in both, shape and color.

On the second image, In red I outlined the shapes with fewer in-between steps so the image is easier to see.

I added a little graph at the bottom of the image. This case representing the acceleration of the blending. In this case, it is a line.

This is the case you have, you have an abrupt change from the original shape into the gradient.

enter image description here

Some programs have the option to accelerate (or decelerate) this blend or morphing.

I accelerated it as you can see on the contours and on the little graph. It reduced the abruptness of the initial color around the original shape but pronounced it on the edges of the shadow.

enter image description here

To compensate for it I would need to separate the blending or morphing into 3 different morphs to represent 3 different stages of acceleration-linear-deceleration. Wich is increasingly tricky to blend the stages. I tried for some minutes but failed to make a nice transition.

The little curve on the right is one known curve on math...

enter image description here

A gaussian bell...

Now you see the difference in a linear transition vs a gaussian transition.

enter image description here

This is why it is so complex to make a vector transition look right compared to a Gaussian filter applied on a raster image.

But not everything is lost

Instead of making a transition of colors, we can play with a transition of transparencies.

On the first image, I have the same color value and a difference in transparency The second value is not 100% transparent so we can still see the shape.

On the second image, you can see that the transition is much smoother than a color transition. Shape 1 has no transparency and the final shape has the transparency of 100%. Same color on both extremes.

But here is a twist. On the image on the right, I used multiply blending mode for the shapes. All the shapes have the same color and transparency (90%) but as the blending is adding, the shape that has now layers of color are darker.

enter image description here

You can play with them. Using transparencies and blending modes look smoother because they are playing with the luminosity and our eyes do not respond to luminosity in a linear way, but a curved way.


In the case of SVG remember that is perfectly fine to have also raster images inside the svg.


All these transitions are a mess even with a simple "outside" shadow.

Things are even more complicated because sometimes we need an average or inside shadow, which not only can be extended with an outline but need to be contracted inwards...

And if you want coloring blurry... forget it. Please use raster images. Haveing a correct combination of raster and vector is Imho the best option.

5
  • You can use the blend as a alpha mask if you wish then you can have color. – joojaa Feb 23 at 19:04
  • Yeap, This can have multiple roads. But I am not exploring masks trying to keep it more SVG friendly. – Rafael Feb 23 at 19:07
  • Can you say more about which programs can accerate the morphing? That's essentially what I'm looking for. – Andrew Swift Feb 25 at 14:10
  • @AndrewSwift yiu can do this in illustrator by making a gradient across a path. But its not enough you also need to erode the shape. This will probably not work for your end application. Anyway astute graphics has a plugin for color curves on vector shape this would be able to change linear to any nonlinear you need. Although to be honest thats 3 lines of code... But meh. – joojaa Feb 26 at 6:32
  • 1
    Thanks for all the info — it gave me a bunch of ideas. What I will do (and will select as the correct answer once it's done) is write a short action script that will take any group of objects in Illustrator and change the opacity distribution from linear to gaussian. – Andrew Swift Mar 1 at 15:40
4

There is no good solution. I mean you can force a solutuon but it will never be a good solution since the standard does not give you any tools for this. The filters were supposed to be enough for you.

You can only use things that whatever subset your SVG engine supports. Using a different application will not change this. Besides filters the only other options to do continious tone are

  1. Gradient meshes, these can do what you ask. Unfortunately support for this in SVG renderers is very limited, so its unlikely that your application platform supports this.

  2. Gradients can do this to some extent, but again a lot of work to segment out the shadow.

This leaves you with making your blends manually. Which has the same zoom problem. Fortunately its easy enough to redistribute the blend values with a script.

Anyway, if you stop using SVG or PDF format then you should have no problem. Just make really large PNG files and scale them down. Or start changing the code behind your app framework to start supporting signed distance fields.

0

Rafael's answer pointed me in the right direction, and I ended up writing an Illustrator Script that redistributes the linear values of an Illustrator blend to something approximating a gaussian distribution.

Left Photoshop gaussian blur · middle Illustrator blend · right this script

enter image description here

Here are the shapes used to create the blurs:

enter image description here

And here's an example of how I might use the blend in a project. I've made the shadow darker than usual to exaggerate the differences:

enter image description here


How does the script work?

After visiting the Wikipedia page on Sigmoid function, I decided to use the arctangent function to create an S-curve of opacities.

Most of the code is necessary simply to convert the arctangent values, which go from -pi to pi, to the range of opacity values of the selected group. Usually this will be from 100 to 0, but it could be from 30 to 0, or from 100 to 20 etc.

To install the script:

  1. copy the code below into a file called Gaussian Blend.jsx
  2. move the file into Applications/Adobe Illustrator 202x/Presets/.../Scripts

The next time you restart Illustrator the script will be listed under File › Scripts › Gaussian Blend.

To use the script:

  1. create a blend from more opaque to less opaque (Object › Blend › Make)
  2. expand the blend (Object › Blend › Expand)
  3. run the script (File › Scripts › Gaussian Blend)

You can adjust the darkness by changing the opacity of the whole group, or you can just change the first or last objects' opacity and re-run the script.


I'm writing a blog post here with more information.


Copy the text below into Gaussian Blend.jsx:


#target illustrator  

/*———————————————————————————————————————— Gaussian Blend.jsx

    Adobe Illustrator Script
    
    Copy into Applications/Adobe Illustrator 202x/Presets/.../Scripts
    
    Takes an expanded blend (Group) where the transparency distribution is
    linear decreasing, and makes the distribution gaussian.

    The result is a more natural blend that imitates a gaussian blur.

    https://graphicdesign.stackexchange.com/questions/145068/how-to-represent-blurry-artwork-with-vectors-illustrator-or-svg 

    by Andy Swift / Svija · May 2021 */

/*———————————————————————————————————————— initialize

    set any path with opacity 0 to opacity 0.5
    there's no reason to have an empty path — it's not visible */

var minVisible = 0.5;


/*  range of arctangent function to use; 5 = arctan(-2.5) to arctan(2.5)
    higher numbers have much steeper transition */

var atan_range = 5;

//———————————————————————————————————————— validate selection

var instr = '\nSelection must be an expanded blend ("group" object with at least 5 steps)';

program:{

  if (app.selection.length > 1)                { alert('Too Many Objects Selected' + instr); break program; }
  if (app.selection.length < 1)                { alert('No selection' + instr); break program; }
  if (app.selection[0].typename != 'GroupItem'){ alert('Please Select a Group' + instr); break program; }

//———————————————————————————————————————— info for existing blend

  var shapes = app.selection[0].pageItems; // front to back, opaque to transp.
  var steps = shapes.length;

  if (steps < 5){ alert('Not enough steps' + instr); break program; }

  var maxOpacity = shapes[0].opacity;
  var minOpacity = shapes[steps - 1].opacity;

  if (minOpacity < minVisible) minOpacity = minVisible;

  var dif = maxOpacity - minOpacity;
  if (Math.abs(dif) < 10){ alert('Not an expanded blend' + instr); break program; }

//———————————————————————————————————————— starting input value & increment

  var inVal = 0 - atan_range / 2;
  var increment = atan_range / (steps-1);

//———————————————————————————————————————— update objects

  for (x=0; x<steps; x++){

    var outVal;
    outVal = Math.atan(inVal);

    outVal = outVal * Math.PI / Math.atan(atan_range / 2); // fill range -pi ... pi
    outVal = 50 - outVal * dif / (Math.PI * 2);            // convert to 100 ... 0
    outVal = outVal - (100 - maxOpacity - minOpacity)/2;   // match min/max opacities

    shapes[x].opacity = outVal;
    inVal += increment;
  }
}

//———————————————————————————————————————— fin

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.