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

Cairo创建阴影Surface叠加后无模糊效果问题求助

问题诊断与解决方案

我帮你梳理下代码里几个可能导致阴影模糊效果不显示的关键点,一步步排查解决:

1. 阴影Surface未初始化透明背景

cairo_image_surface_create创建的ARGB32格式Surface,初始像素是未定义的垃圾数据,不是默认透明的。当你绘制圆角矩形并执行模糊时,这些随机垃圾像素会被一起模糊,直接干扰甚至覆盖掉原本的阴影效果。

修复方法:在绘制阴影前,先把整个阴影Surface清除为透明:

cairo_t *cr_shadow = cairo_create(shadow);
// 先填充透明背景,清除垃圾像素
cairo_set_source_rgba(cr_shadow, 0, 0, 0, 0);
cairo_paint(cr_shadow);
// 再绘制圆角矩形阴影
draw_rounded_rect(cr_shadow, x_o+offset, y_o+offset, width, height, radius_int, 1, 1);
cairo_set_source_rgba(cr_shadow, 0, 0, 0, 1);
cairo_fill(cr_shadow);

2. 阴影绘制坐标可能超出Surface范围

如果x_o+offset + width或y_o+offset + height的值超过了阴影Surface的尺寸,圆角矩形会被裁剪,模糊后自然看不到完整的阴影。

修复方法:确保阴影矩形完全落在阴影Surface内。比如你原始绘制的矩形是(x_o, y_o)到(x_o+rect_w, y_o+rect_h),那阴影的尺寸应该和原矩形一致,而不是用整个Surface的宽高:

// 用原矩形的尺寸,而不是Surface的width/height
draw_rounded_rect(cr_shadow, x_o + offset, y_o + offset, rect_w, rect_h, radius_int, 1, 1);

3. 绘制顺序搞反了

阴影应该在原始内容绘制之前叠加到原始Surface上,否则原始内容会完全覆盖住阴影,导致你看不到模糊效果。

修复方法:调整绘制流程:

  1. 先绘制模糊后的阴影到原始上下文
  2. 再绘制原始的圆角矩形内容

4. 可选:降低阴影的不透明度

你当前设置阴影为完全不透明(alpha=1),叠加后可能和原始内容融合得太生硬,甚至看起来像黑色块而非阴影。建议把alpha值调低,比如设为0.7,让阴影更自然:

cairo_set_source_rgba(cr_shadow, 0, 0, 0, 0.7);

修正后的完整代码示例

// 保存原始上下文,避免被覆盖
cairo_t *original_cr = c;
// 获取原始Surface的尺寸,确保阴影Surface和它一致
int srf_width = cairo_image_surface_get_width(srf);
int srf_height = cairo_image_surface_get_height(srf);

cairo_surface_t *shadow = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, srf_width, srf_height); 
cairo_t *shadow_cr = cairo_create(shadow); 

// 清除阴影Surface为透明
cairo_set_source_rgba(shadow_cr, 0, 0, 0, 0);
cairo_paint(shadow_cr);

// 绘制偏移后的圆角矩形阴影
draw_rounded_rect(shadow_cr, x_o+offset, y_o+offset, rect_w, rect_h, radius_int, 1, 1); 
cairo_set_source_rgba(shadow_cr, 0, 0, 0, 0.7); 
cairo_fill(shadow_cr); 

// 执行模糊
blur_image_surface(shadow,10); 

// 回到原始上下文,先绘制阴影
cairo_set_source_surface(original_cr, shadow, 0, 0); 
cairo_paint(original_cr); 

// 再绘制原始的圆角矩形内容
draw_rounded_rect(original_cr, x_o, y_o, rect_w, rect_h, radius_int, 1, 1);
cairo_set_source_rgba(original_cr, 1, 1, 1, 1); // 替换成你原始内容的颜色
cairo_fill(original_cr);

// 清理资源
cairo_destroy(shadow_cr); 
cairo_surface_destroy(shadow); 
c = original_cr;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:54:05