如何用矢量(Illustrator 或 SVG)表示模糊的图稿?

平面设计 adobe-illustrator svg 混合 模糊 过渡
2022-02-21 09:45:36

我有一个反复出现的问题,我想一劳永逸地解决:如何创建模糊矢量图像

例如,这个位图图像代表一个矩形的投影:

漂亮的位图模糊

用 50 个左右的圆角矩形应该可以在 SVG 或 Illustrator 文件中很好地表示它。

主要问题是:

  1. 混合使用灰度的线性分布,因此边缘不会正确淡出
  2. 图像跟踪无法识别图像的平滑性并添加数千个点,导致图像大参差不齐

我正在寻找某种方法来创建正确的灰度分布,同时保持模糊效果。

这只是一个简单的例子,但我经常需要更复杂的模糊图像。

我可以从一个锋利的对象开始,也可以手动创建“第一个和最后一个”路径并在它们之间混合。那里的问题是有正确的水平。

这是 50 路径混合的样子:

在此处输入图像描述

从灰色到白色的过渡太突然了。

有谁知道如何创建路径以更好地表示模糊内容?

在这一点上,我很乐意为这项单一任务使用全新的应用程序。

[编辑]我知道 SVG 模糊效果,但它不适用于我的目的。我的主要用例之一是在 Mac 应用程序中创建图像,而 SVG 过滤器被忽略。对于网络使用,我还发现缩放页面会导致 SVG 过滤器缩放不正确。

3个回答

让我稍微探讨一下这个话题。

形状

如果我们试图用矢量形状来做到这一点,那么形状本身必须是正确的。很容易出现变形或不成比例的形状。

在此处输入图像描述

准备它们的一种方法是复制整体形状并使用形状上较粗的轮廓线,它将成为阴影的最终边界。

在此处输入图像描述

现在我们有 2 个要混合的形状。它们应该具有相同数量的节点。

混合或变形

通常,矢量设计软件上可用的一种工具是混合(或变形)形状。最简单的方法是对形状和颜色进行线性混合。

在第二张图片中,我用红色勾勒出了中间步骤较少的形状,因此图像更容易看到。

我在图像底部添加了一个小图表。这种情况代表了混合的加速。在这种情况下,它是一条线。

这就是您所拥有的情况,您从原始形状突然变为渐变。

在此处输入图像描述

一些程序可以选择加速(或减速)这种混合或变形。

正如你在等高线和小图上看到的那样,我加速了它。它降低了原始形状周围初始颜色的突然性,但在阴影边缘突出。

在此处输入图像描述

为了弥补它,我需要将混合或变形分离为 3 个不同的变形,以表示加速-线性-减速的 3 个不同阶段。Wich 越来越难以融合这些阶段。我尝试了几分钟,但未能做出很好的过渡。

右边的小曲线是已知的数学曲线...

在此处输入图像描述

高斯钟声...

现在您看到了线性转换与高斯转换的区别。

在此处输入图像描述

这就是为什么与应用于光栅图像的高斯滤波器相比,使矢量过渡看起来正确如此复杂的原因。

但并非一切都丢失了

我们可以玩透明胶片的过渡,而不是进行颜色过渡。

在第一张图像上,我有相同的颜色值和透明度差异第二个值不是 100% 透明,所以我们仍然可以看到形状。

在第二张图像上,您可以看到过渡比颜色过渡要平滑得多。形状 1 没有透明度,最终形状的透明度为 100%。两个极端的颜色相同。

但这里有一个转折。在右侧的图像中,我对形状使用了多重混合模式。所有形状都具有相同的颜色和透明度 (90%),但随着混合的添加,现在具有颜色层的形状更暗。

在此处输入图像描述

你可以和他们一起玩。使用透明胶片和混合模式看起来更平滑,因为它们正在使用亮度,我们的眼睛不会以线性方式响应亮度,而是以曲线方式响应。


在 SVG 的情况下,记住在 svg 中也有光栅图像是非常好的。


即使有一个简单的“外部”阴影,所有这些过渡都是一团糟。

事情就更复杂了,因为有时我们需要一个平均或内部阴影,它不仅可以用轮廓延伸,还需要向内收缩......

如果你想模糊着色......算了吧。请使用光栅图像。正确组合光栅和矢量是 Imho 的最佳选择。

没有好的解决办法。我的意思是你可以强制一个解决方案,但它永远不会是一个好的解决方案,因为标准没有为此提供任何工具。过滤器应该足以满足您的需求。

您只能使用 SVG 引擎支持的任何子集。使用不同的应用程序不会改变这一点。除了过滤器之外,做连续音的唯一其他选项是

  1. 渐变网格,这些可以满足您的要求。不幸的是,SVG 渲染器对此的支持非常有限,因此您的应用程序平台不太可能支持这一点。

  2. 渐变可以在一定程度上做到这一点,但要分割出阴影又需要做很多工作。

这使您可以手动进行混合。哪个具有相同的缩放问题。幸运的是,它很容易用脚本重新分配混合值。

无论如何,如果您停止使用 SVG 或 PDF 格式,那么您应该没有问题。只需制作非常大的 PNG 文件并按比例缩小它们。或者开始更改应用程序框架背后的代码以开始支持有符号距离字段。

Rafael 的回答为我指明了正确的方向,我最终编写了一个Illustrator 脚本,将 Illustrator 混合的线性值重新分配为近似高斯分布的东西。

左侧Photoshop 高斯模糊·中间Illustrator 混合·右侧此脚本

在此处输入图像描述

以下是用于创建模糊的形状:

在此处输入图像描述

这是我如何在项目中使用混合的示例。我使阴影比平时更暗以夸大差异:

在此处输入图像描述


脚本是如何工作的?

在访问了Sigmoid 函数的 Wikipedia 页面后,我决定使用反正切函数来创建不透明度的 S 曲线

大多数代码只需将反正切值(从-pi 到 pi)转换为所选组的不透明度值范围。通常这将是从 100 到 0,但也可能是从 30 到 0,或从 100 到 20 等。

要安装脚本:

  1. 将以下代码复制到名为Gaussian Blend.jsx的文件中
  2. 将文件移动到Applications/Adobe Illustrator 202x/Presets/.../Scripts

下次重新启动 Illustrator 时,脚本将列在文件 › 脚本 › Gaussian Blend下。

要使用脚本:

  1. 创建从更不透明到更不透明的混合(对象 › 混合 › 制作)
  2. 展开混合(对象 › 混合 › 展开)
  3. 运行脚本(文件 › 脚本 › 高斯混合)

您可以通过更改整个组的不透明度来调整暗度,或者您可以只更改第一个或最后一个对象的不透明度并重新运行脚本


我在这里写一篇博文,提供更多信息。


将下面的文本复制到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