如何在不改动原始黑色像素的前提下实现带S曲线过渡的模糊?
适配需求的位图边缘平滑过渡模糊方案
高斯模糊的局限性解释
你遇到的轮廓线问题,根源在于高斯函数的无限延伸特性——即使按理论截断半径扩展区域,仍会有极微弱的像素值渗透到原始黑色区域,叠加红色方块后就显现出了轮廓。高斯模糊本质是全局加权平均,无法做到严格的“不碰原始区域”的边界控制。
最优方案:距离场 + S曲线映射
这是完全匹配你需求的位图实现方式,核心思路是基于像素到原始形状边缘的距离来生成过渡,完全不修改原始黑色像素:
- 步骤1:计算有符号距离场
对每个像素计算到原始黑色区域边缘的有符号距离:原始黑色区域内的像素距离为负,外部为正,边缘像素为0。可以用快速行进法(Fast Marching Method)高效计算,避免暴力遍历的低效。 - 步骤2:S曲线映射灰度值
设定你的过渡宽度(比如你之前用的15px),用S曲线函数(如smoothstep)将距离值映射为灰度:- 当距离 ≤ -15px:输出纯黑(保持原始像素)
- 当距离 ≥15px:输出纯白
- 中间区间:用
smoothstep(-15, 15, 距离)计算平滑过渡的灰度值smoothstep的公式为:
float smoothstep(float a, float b, float x) { float t = clamp((x - a) / (b - a), 0.0, 1.0); return t * t * (3.0 - 2.0 * t); } - 步骤3:合成图像
把计算出的灰度值覆盖到原始图像的非黑色区域,原始黑色区域完全保留。
这种方法的优势:
- 严格保证原始黑色像素不被修改
- 过渡完全沿形状法线方向,平滑度可精准控制
- 效果和矢量图实现的逻辑高度一致,适配位图场景
简易替代方案:蒙版双边模糊
如果不想实现距离场,可以用蒙版控制模糊范围:
- 提取原始黑色区域的蒙版,反转得到仅包含过渡区域的蒙版
- 只对蒙版覆盖的区域应用双边模糊(双边模糊能减少边缘糊化,但这里是针对性模糊过渡区)
- 合成回原始图像
但这种方法无法做到像距离场那样精准的S曲线过渡,仍可能有微弱的边缘影响。
内容的提问来源于stack exchange,提问作者mpen
相关产品推荐
相关产品推荐

