当前位置:首页 > 技术 > 正文内容

基于 GDI+ 的 C# 高斯模糊无损处理实现

访客 技术 2026年6月9日 1
在使用 C# 进行图像处理时,若需快速实现高斯模糊且不修改原始图像,可通过调用 GDI+ 的底层接口完成。本文介绍一种通过 `GdipBitmapCreateApplyEffect` 实现非破坏性模糊处理的方法,其核心在于正确传递句柄与结果回收。 该方法利用 GDI+ 提供的特效接口,将原图作为输入源,生成一个新图像对象,避免直接修改原始数据。关键点在于:函数执行后返回的是指向新图像的指针(IntPtr),必须通过特定方式将其转换为 .NET 可识别的 Bitmap 实例。 以下为完整实现逻辑: 1 /// 2 /// 对指定区域应用高斯模糊效果,并返回新图像 3 /// 4 /// 原始图像 5 /// 处理区域 6 /// 模糊半径(0-255) 7 /// 是否扩展边缘像素 8 /// 处理后的图像副本 9 public static Bitmap ApplyGaussianBlur(this Bitmap source, Rectangle region, float blurRadius = 10, bool extendEdges = false) 10 { 11 var outputImage = new Bitmap(source); 12 13 IntPtr effectHandle; 14 var parameters = new BlurParameters { Radius = blurRadius, ExpandEdges = extendEdges }; 15 16 if (blurRadius < 0 || blurRadius > 255) 17 throw new ArgumentOutOfRangeException("模糊半径必须在 [0, 255] 范围内"); 18 19 // 创建高斯模糊效果实例 20 int result = GdipCreateEffect(BlurEffectGuid, out effectHandle); 21 if (result != 0) 22 throw new ExternalException("当前系统不支持 GDI+ 1.1 以上版本,或操作系统不满足要求"); 23 24 // 将参数结构体写入内存 25 IntPtr paramPtr = Marshal.AllocHGlobal(Marshal.SizeOf(parameters)); 26 Marshal.StructureToPtr(parameters, paramPtr, true); 27 28 // 设置效果参数 29 GdipSetEffectParameters(effectHandle, paramPtr, (uint)Marshal.SizeOf(parameters)); 30 31 // 获取源图像句柄和目标区域 32 IntPtr srcHandle = source.NativeHandle(); 33 IntPtr destHandle = IntPtr.Zero; 34 35 // 执行模糊处理,生成新图像 36 int status = GdipBitmapCreateApplyEffect( 37 ref srcHandle, 38 1, 39 effectHandle, 40 ref region, 41 ref region, 42 out destHandle, 43 false, 44 IntPtr.Zero, 45 0 46 ); 47 48 // 成功则从句柄还原为 Bitmap 49 if (status == 0 && destHandle != IntPtr.Zero) 50 { 51 outputImage = destHandle.NativeBitmapPtrToBitmap(); 52 } 53 54 // 清理资源 55 GdipDeleteEffect(effectHandle); 56 Marshal.FreeHGlobal(paramPtr); 57 58 return outputImage; 59 } 其中两个辅助方法用于从原生句柄恢复 .NET 图像对象: 1 /// 2 /// 从 GDI+ 原生句柄创建 Bitmap 实例 3 /// 4 /// 原生图像句柄 5 /// 对应的 Bitmap 6 public static Bitmap NativeBitmapPtrToBitmap(this IntPtr handle) 7 { 8 return typeof(Bitmap).InvokeStaticPrivateMethod("FromGDIplus", handle); 9 } 10 11 /// 12 /// 调用类型中的私有静态方法 13 /// 14 /// 返回类型 15 /// 目标类型 16 /// 方法名 17 /// 参数列表 18 /// 方法返回值 19 public static TResult InvokeStaticPrivateMethod(this Type type, string methodName, params object[] args) 20 { 21 var method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic); 22 if (method == null) 23 throw new InvalidOperationException($"无法找到私有静态方法: {methodName} in {type.FullName}"); 24 25 return (TResult)method.Invoke(null, args); 26 } 此方案的优势在于: - 不改变原始图像; - 支持局部区域处理; - 利用系统级优化,性能较高; - 可扩展至其他 GDI+ 特效。 注意:使用完毕后应确保释放返回的图像资源,防止内存泄漏。建议结合 `IDisposable` 或 `using` 语句管理生命周期。 参考文档:[MSDN - GdipBitmapCreateApplyEffect](https://learn.microsoft.com/en-us/windows/win32/api/gdiplus/nc-gdiplus-gpbitmapcreateapplyeffect)
标签: GDI+

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。