哞哞快的 C# 高斯模糊实现(续)
昨天刚写了《哞哞快的 C# 高斯模糊实现》,里边提到了用原作者的方法实现对图像快速的高斯模糊处理,说实话,我没看懂,主要是没看懂原理,怎么就“把图片给处理了”,大概是调用了 GDIPlus.dll 里边的函数,所以我看不到算法和细节,但这正是我要的——专业的人才做专业的事儿,我不懂图像处理,我只想有个 void 帮我随时把某个图像处理掉,最好还是免费、开源、快速的 ^^
昨天写完这个之后,继续去研究方法里作者提到的一个函数“int GdipBitmapCreateApplyEffect()”,据说可以不修改原图,将处理后的效果写进另一个图像中,自己照猫画虎的写了写,不出意外的,不成功。程序也不报错,调试了一下,发现函数的处理结果是“OK”,那就是我自己写的有问题。冷静想想……找找资料
谷歌出一篇,在 CodePlex 上有一个对图像处理的项目,里边使用到了 GDIPlus.dll,下载下来步步跟踪,发现了自己的问题:函数的参数传递的是 IntPtr,就是句柄,也可以理解为“指针”,经过函数处理之后,即便成功了,也需要额外的工作,就是把处理后的图像“写回”到某个 Bitmap 对象中去。我之前没成功就是因为函数执行完了,以为定义的新的 Bitmap 对象就被自动修改了,实际上没有。
想到了自己的问题,就看人家怎么处理的,结果,又是两个俺不懂的函数,不过不影响理解原理。拷贝到方法内,运行,成功!Project 下载
/// <summary>
/// 使用高斯模糊效果创建一个新的图像
/// </summary>
/// <returns></returns>
public static Bitmap CreateNewWithEffect(this Bitmap image, ref Rectangle Rect, float Radius = , bool ExpandEdge = false)
{
// 新图像
Bitmap newImage = new Bitmap(image); int Result;
IntPtr BlurEffect;
BlurParameters BlurPara;
if ((Radius < ) || (Radius > ))
{
throw new ArgumentOutOfRangeException("Radius 参数错误,半径必须在 [0,255] 范围内");
}
BlurPara.Radius = Radius;
BlurPara.ExpandEdges = ExpandEdge;
Result = GdipCreateEffect(BlurEffectGuid, out BlurEffect); if (Result == )
{
IntPtr Handle = Marshal.AllocHGlobal(Marshal.SizeOf(BlurPara));
Marshal.StructureToPtr(BlurPara, Handle, true);
GdipSetEffectParameters(BlurEffect, Handle, (uint)Marshal.SizeOf(BlurPara));
// 准备参数
IntPtr scrImagePointer = image.NativeHandle(); // 原图像的句柄
Rectangle newImageRect = new Rectangle(Rect.Location, Rect.Size); // 创建一个和要处理的范围同样尺寸的 Rectangle
IntPtr newImagePointer = IntPtr.Zero; //GdipBitmapApplyEffect(image.NativeHandle(), BlurEffect, ref Rect, false, IntPtr.Zero, 0);
// 使用GdipBitmapCreateApplyEffect函数可以不改变原始的图像,而把模糊的结果写入到一个新的图像中
int ok = GdipBitmapCreateApplyEffect(ref scrImagePointer, , BlurEffect, ref Rect,ref newImageRect,out newImagePointer, false, IntPtr.Zero, ); if (ok == ) // 成功
{
// 执行后,newImagePointer 应不为 IntPtr.Zero
if (newImagePointer != IntPtr.Zero)
{
newImage = newImagePointer.NativeBitmapPtrToBitmap();
}
} GdipDeleteEffect(BlurEffect);
Marshal.FreeHGlobal(Handle);
}
else
{
throw new ExternalException("不支持的GDI+版本,必须为GDI+1.1及以上版本,且操作系统要求为Win Vista及之后版本.");
}
return newImage;
}
下面是函数运行完,负责将处理后的数据“赋值”到新的图像的两个俺不懂的方法
/// <summary>
/// Gets a Bitmap object for a native GDI+ bitmap handle.
/// </summary>
/// <param name="nativeBitmap">The native handle to get the bitmap for.</param>
/// <returns>A Bitmap.</returns>
public static Bitmap NativeBitmapPtrToBitmap(this IntPtr nativeBitmap)
{
return typeof(Bitmap).InvokeStaticPrivateMethod<Bitmap>("FromGDIplus", nativeBitmap);
} /// <summary>
/// Invokes a non-public static method for a Type.
/// </summary>
/// <typeparam name="TResult">The return type of the static method.</typeparam>
/// <param name="type">The Type to invoke the static method for.</param>
/// <param name="methodName">The name of the static method.</param>
/// <param name="args">The arguments for the static method.</param>
/// <returns>The return value of the static method.</returns>
/// <exception cref="System.InvalidOperationException">Static method could not be located.</exception>
public static TResult InvokeStaticPrivateMethod<TResult>(this Type type, string methodName, params object[] args)
{
MethodInfo lmiInfo = type.GetMethod(methodName,
BindingFlags.Static | BindingFlags.NonPublic); if (lmiInfo != null)
return (TResult)(lmiInfo.Invoke(null, args));
else
throw new InvalidOperationException(
string.Format(
"Static method '{0}' could not be located in object type '{1}'.",
methodName, type.FullName));
}
三个函数配合后,就会得到一个新的经过高斯模糊的图像,看 MSDN 介绍,有个很重要的四儿:经过“GdiBitmapCreateApplyEffect()”会返回一个指向新图像的指针对象,在资源不用时需要手动进行释放,我的方法里还没有添加完善的释放资源的逻辑,回头还需要研究研究。原文地址是:http://msdn.microsoft.com/en-us/library/windows/desktop/ms536320(v=vs.85).aspx

运行后

哞哞快的 C# 高斯模糊实现(续)的更多相关文章
- 哞哞快的 C# 高斯模糊实现
冲动来自于 bing best 这个小工具,非常短小精干,里边的设置界面非常精美而且背景是一张模糊效果的图片,十分养眼,遂想,收集一下实现方式放到类库里以后肯定用得上.一通百度.谷歌.博客园,换了好多 ...
- 安装python sklearn经验总结
1. 需要安装 numpy, scipy, 和sklearn和ipython,Cython sklearn,ipython, Cython都可以通过pip来安装.但scipy,可能还有numpy必须通 ...
- v4l2驱动编写篇【转】
转自:http://blog.csdn.net/michaelcao1980/article/details/53008418 大部分所需的信息都在这里.作为一个驱动作者,当挖掘头文件的时候,你可能也 ...
- Redis分布式锁的一点小理解
1.在分布式系统中,我们使用锁机制只能保证同一个JVM中一次只有一个线程访问,但是在分布式的系统中锁就不起作用了,这时候就要用到分布式锁(有多种,这里指 redis) 2.在 redis当中可以使用命 ...
- 《Dotnet9》建站-记录建站过程中使用的一些网址
时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...
- DHCP服务——服务端 和 客户端 配置
转载注明出处:https://www.cnblogs.com/kelamoyujuzhen/p/9520341.html 实验环境 rhel-server-6.4-x86_64-dvd(ED2000 ...
- .NET CORE下最快比较两个文件内容是否相同的方法 - 续
.NET CORE下最快比较两个文件内容是否相同的方法 - 续 在上一篇博文中, 我使用了几种方法试图找到哪个是.NET CORE下最快比较两个文件的方法.文章发布后,引起了很多博友的讨论, 在此我对 ...
- [译]Godot系列教程三 - 场景实例化(续)
场景实例化(续) 要点 场景实例化带来很多便利的用法,总体来说有: 将场景细分,更便于管理 相对于某些引擎中的Prefab组件更灵活,并且在许多方面更强大 是一种设计更复杂的游戏流程甚至UI的方式 这 ...
- 高斯模糊算法的 C++ 实现
2008 年在一个 PS 讨论群里,有网友不解 Photoshop 的高斯模糊中的半径是什么含义,因此当时我写了这篇文章: 对Photoshop高斯模糊滤镜的算法总结: 在那篇文章中,主要讲解了高斯模 ...
随机推荐
- 谷歌、火狐浏览器下实现JS跨域iframe高度自适应的完美解决方法,跨域调用JS不再是难题!
谷歌.火狐浏览器下实现JS跨域iframe高度自适应的解决方法 导读:今天开发的时候遇到个iframe自适应高度的问题,相信大家对这个不陌生,但是一般我们都是在同一个项目使用iframe嵌套页面,这个 ...
- 10分钟学会Linux
10分钟学会Linux有点夸张,可是能够让一个新手初步熟悉Linux中最重要最主要的知识,本文翻译的英文网页在众多Linux入门学习的资料中还是很不错的. 英文地址:http://freeengine ...
- JavaEE Tutorials (2) - 使用教程示例
2.1 必要软件27 2.1.1 Java EE 7软件开发包28 2.1.2 Java平台标准版28 2.1.3 Java EE 7教程组件28 2.1.4 NetBeans IDE29 2.1.5 ...
- Google软件构建工具Bazel
转载Google软件构建工具Bazel FAQ 本文是我的翻译,原文在这里.欢迎转载,转载请注名本文作者和原始链接注:如果想了解Bazel的原理,可以看看我之前翻译的Google Blaze原理及使用 ...
- Swift # 柯里化函数
前言 此次文章,讲述的是Swift的一个新特性(柯里化函数),可能很多iOS开发人员是第一次听这个词汇,包括我自己也是,自己也用了几天时间才总结出来,希望能帮助到各位咯,个人感觉偏向有开发经验的码友, ...
- 【百度地图API】如何快速创建带有标注的地图?——快速创建地图工具+如何标注商家
原文:[百度地图API]如何快速创建带有标注的地图?--快速创建地图工具+如何标注商家 摘要: 如果你不会程序,如果你不想写代码. 如果你想拥有一张自己的地图,如果你想在该地图上标注出你商店的位置. ...
- sql server、c# 命名规范
查了不少资料,没有我想要的. 还不如下载 官方的 数据 Northwind ,pubs 参见 https://www.microsoft.com/en-us/download/confirmation ...
- ym——android源代码大放送(实战开发必备)
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! 目录 PATH 列表 卷序列号为 000A-8F50 E:. │ javaapk.c ...
- RegularExpressionValidator控件
原文:RegularExpressionValidator控件 ★搜Asp.net★(www.soAsp.net),为专业技术文档网站.包括Asp.net开发技术文档·C#开发技术文档·Access/ ...
- java 转成字符串 json 数组和迭代
当你需要转成一串一串的json 排列 .当内容和遍历它们. 首页进口 net.sf.json.JSONArray和net.sf.json.JSONObject 两个jar 包 String str = ...