You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在HTML Canvas及WebGL中实现图片边缘模糊淡入效果

在Canvas中实现图片边缘模糊淡入效果

Canvas 2D 快速实现方案

不需要复杂逻辑,通过图层叠加就能实现仅边缘模糊的效果:

  1. 绘制清晰原图
    先将原图按正常尺寸绘制到画布,作为底层清晰内容:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.src = '你的图片路径';
img.onload = () => {
    canvas.width = img.width;
    canvas.height = img.height;
    // 绘制清晰原图
    ctx.drawImage(img, 0, 0);
    // 添加边缘模糊效果
    addEdgeBlur(ctx, img.width, img.height);
};
  1. 叠加模糊边缘层
    核心思路:先绘制模糊后的完整图片,再用径向渐变遮罩“保留边缘、挖去中间”,最后叠加到原图上:
function addEdgeBlur(ctx, width, height) {
    // 1. 创建离屏画布绘制模糊后的图片
    const offscreenCanvas = document.createElement('canvas');
    offscreenCanvas.width = width;
    offscreenCanvas.height = height;
    const offCtx = offscreenCanvas.getContext('2d');
    offCtx.filter = 'blur(8px)';
    offCtx.drawImage(img, 0, 0);

    // 2. 创建径向渐变遮罩:中间透明,边缘不透明
    const gradient = ctx.createRadialGradient(
        width / 2, height / 2, width * 0.4,
        width / 2, height / 2, width / 2
    );
    gradient.addColorStop(0, 'transparent');
    gradient.addColorStop(1, 'rgba(0,0,0,1)');

    // 3. 用遮罩裁剪模糊层,只保留边缘部分
    ctx.save();
    ctx.globalCompositeOperation = 'destination-in';
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, width, height);
    ctx.drawImage(offscreenCanvas, 0, 0);
    ctx.restore();
}

调整径向渐变的width * 0.4参数可以控制模糊边缘的宽度:数值越小,模糊边缘越宽;反之则越窄。

WebGL 高性能方案(适合大尺寸/动态场景)

通过自定义片段着色器直接实现边缘模糊,性能比Canvas 2D离屏渲染更优:

  1. 顶点着色器(基础纹理映射)
attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main() {
    gl_Position = vec4(a_position, 0.0, 1.0);
    v_texCoord = a_texCoord;
}
  1. 片段着色器(实现边缘模糊+淡入)
    核心逻辑:根据像素到图片中心的距离,动态调整模糊程度和透明度:
precision mediump float;
uniform sampler2D u_texture;
uniform vec2 u_resolution;
varying vec2 v_texCoord;

// 简易高斯模糊采样函数
vec4 blur(sampler2D tex, vec2 uv, vec2 resolution, float radius) {
    vec4 color = vec4(0.0);
    float total = 0.0;
    for (float x = -radius; x <= radius; x++) {
        for (float y = -radius; y <= radius; y++) {
            float weight = (1.0 - abs(x)/radius) * (1.0 - abs(y)/radius);
            color += texture2D(tex, uv + vec2(x, y)/resolution) * weight;
            total += weight;
        }
    }
    return color / total;
}

void main() {
    vec2 center = vec2(0.5, 0.5);
    float dist = distance(v_texCoord, center);
    // 控制模糊过渡范围:0.4为清晰区域半径,0.5为模糊区域边界
    float blurRadius = smoothstep(0.4, 0.5, dist) * 8.0;
    // 边缘淡入透明度控制
    float alpha = smoothstep(0.5, 0.45, dist);
    
    vec4 blurredColor = blur(u_texture, v_texCoord, u_resolution, blurRadius);
    vec4 originalColor = texture2D(u_texture, v_texCoord);
    // 混合清晰原图与模糊边缘
    gl_FragColor = mix(originalColor, blurredColor, 1.0 - alpha);
    gl_FragColor.a = alpha;
}

修改smoothstep(0.4, 0.5, dist)的参数可以调整模糊边缘的过渡宽度,*8.0对应你需要的最大模糊半径(8px)。

注意事项

  • Canvas 2D方案适合快速验证、小尺寸图片场景;WebGL方案适合大图片或需要实时更新的交互场景。
  • 两种方案都可通过调整参数匹配示例图的效果,多测试几组数值即可达到理想状态。

内容的提问来源于stack exchange,提问作者slowloris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:57:46