using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Diagnostics; namespace Adrian.PhotoX.Lib
{
[Serializable]
public enum BlurType
{
Both,
HorizontalOnly,
VerticalOnly,
} [Serializable]
public class GaussianBlur
{
private int _radius = ;
private int[] _kernel;
private int _kernelSum;
private int[,] _multable;
private BlurType _blurType; public GaussianBlur()
{
PreCalculateSomeStuff();
} public GaussianBlur(int radius)
{
_radius = radius;
PreCalculateSomeStuff();
} private void PreCalculateSomeStuff()
{
int sz = _radius * + ;
_kernel = new int[sz];
_multable = new int[sz, ];
for (int i = ; i <= _radius; i++)
{
int szi = _radius - i;
int szj = _radius + i;
_kernel[szj] = _kernel[szi] = (szi + ) * (szi + );
_kernelSum += (_kernel[szj] + _kernel[szi]);
for (int j = ; j < ; j++)
{
_multable[szj, j] = _multable[szi, j] = _kernel[szj] * j;
}
}
_kernel[_radius] = (_radius + ) * (_radius + );
_kernelSum += _kernel[_radius];
for (int j = ; j < ; j++)
{
_multable[_radius, j] = _kernel[_radius] * j;
}
} public long t1;
public long t2;
public long t3;
public long t4; public Bitmap ProcessImage(Image inputImage)
{
Bitmap origin = new Bitmap(inputImage);
Bitmap blurred = new Bitmap(inputImage.Width, inputImage.Height); using (RawBitmap src = new RawBitmap(origin))
{
using (RawBitmap dest = new RawBitmap(blurred))
{
int pixelCount = src.Width * src.Height;
//Stopwatch sw = new Stopwatch();
//sw.Start();
int[] b = new int[pixelCount];
int[] g = new int[pixelCount];
int[] r = new int[pixelCount]; int[] b2 = new int[pixelCount];
int[] g2 = new int[pixelCount];
int[] r2 = new int[pixelCount];
//sw.Stop();
//t1 = sw.ElapsedMilliseconds; int offset = src.GetOffset();
int index = ;
unsafe
{
//sw.Reset();
//sw.Start(); byte* ptr = src.Begin;
for (int i = ; i < src.Height; i++)
{
for (int j = ; j < src.Width; j++)
{
b[index] = *ptr;
ptr++;
g[index] = *ptr;
ptr++;
r[index] = *ptr;
ptr++; ++index;
}
ptr += offset;
} //sw.Stop();
//t2 = sw.ElapsedMilliseconds; int bsum;
int gsum;
int rsum;
int read;
int start = ;
index = ; //sw.Reset();
//sw.Start(); if (_blurType != BlurType.VerticalOnly)
{
for (int i = ; i < src.Height; i++)
{
for (int j = ; j < src.Width; j++)
{
bsum = gsum = rsum = ;
read = index - _radius; for (int z = ; z < _kernel.Length; z++)
{
//if (read >= start && read < start + src.Width)
//{
// bsum += _multable[z, b[read]];
// gsum += _multable[z, g[read]];
// rsum += _multable[z, r[read]];
// sum += _kernel[z];
//} if (read < start)
{
bsum += _multable[z, b[start]];
gsum += _multable[z, g[start]];
rsum += _multable[z, r[start]];
}
else if (read > start + src.Width - )
{
int idx = start + src.Width - ;
bsum += _multable[z, b[idx]];
gsum += _multable[z, g[idx]];
rsum += _multable[z, r[idx]];
}
else
{
bsum += _multable[z, b[read]];
gsum += _multable[z, g[read]];
rsum += _multable[z, r[read]];
}
++read;
} //b2[index] = (bsum / sum);
//g2[index] = (gsum / sum);
//r2[index] = (rsum / sum); b2[index] = (bsum / _kernelSum);
g2[index] = (gsum / _kernelSum);
r2[index] = (rsum / _kernelSum); if (_blurType == BlurType.HorizontalOnly)
{
//byte* pcell = dest[j, i];
//*pcell = (byte)(bsum / sum);
//pcell++;
//*pcell = (byte)(gsum / sum);
//pcell++;
//*pcell = (byte)(rsum / sum);
//pcell++; byte* pcell = dest[j, i];
*pcell = (byte)(bsum / _kernelSum);
pcell++;
*pcell = (byte)(gsum / _kernelSum);
pcell++;
*pcell = (byte)(rsum / _kernelSum);
pcell++;
} ++index;
}
start += src.Width;
}
}
if (_blurType == BlurType.HorizontalOnly)
{
return blurred;
} //sw.Stop();
//t3 = sw.ElapsedMilliseconds; //sw.Reset();
//sw.Start(); int tempy;
for (int i = ; i < src.Height; i++)
{
int y = i - _radius;
start = y * src.Width;
for (int j = ; j < src.Width; j++)
{
bsum = gsum = rsum = ;
read = start + j;
tempy = y;
for (int z = ; z < _kernel.Length; z++)
{
//if (tempy >= 0 && tempy < src.Height)
//{
// if (_blurType == BlurType.VerticalOnly)
// {
// bsum += _multable[z, b[read]];
// gsum += _multable[z, g[read]];
// rsum += _multable[z, r[read]];
// }
// else
// {
// bsum += _multable[z, b2[read]];
// gsum += _multable[z, g2[read]];
// rsum += _multable[z, r2[read]];
// }
// sum += _kernel[z];
//} if (_blurType == BlurType.VerticalOnly)
{
if (tempy < )
{
bsum += _multable[z, b[j]];
gsum += _multable[z, g[j]];
rsum += _multable[z, r[j]];
}
else if (tempy > src.Height - )
{
int idx = pixelCount - (src.Width - j);
bsum += _multable[z, b[idx]];
gsum += _multable[z, g[idx]];
rsum += _multable[z, r[idx]];
}
else
{
bsum += _multable[z, b[read]];
gsum += _multable[z, g[read]];
rsum += _multable[z, r[read]];
}
}
else
{
if (tempy < )
{
bsum += _multable[z, b2[j]];
gsum += _multable[z, g2[j]];
rsum += _multable[z, r2[j]];
}
else if (tempy > src.Height - )
{
int idx = pixelCount - (src.Width - j);
bsum += _multable[z, b2[idx]];
gsum += _multable[z, g2[idx]];
rsum += _multable[z, r2[idx]];
}
else
{
bsum += _multable[z, b2[read]];
gsum += _multable[z, g2[read]];
rsum += _multable[z, r2[read]];
}
} read += src.Width;
++tempy;
} byte* pcell = dest[j, i]; //pcell[0] = (byte)(bsum / sum);
//pcell[1] = (byte)(gsum / sum);
//pcell[2] = (byte)(rsum / sum); pcell[] = (byte)(bsum / _kernelSum);
pcell[] = (byte)(gsum / _kernelSum);
pcell[] = (byte)(rsum / _kernelSum);
}
}
//sw.Stop();
//t4 = sw.ElapsedMilliseconds;
}
}
} return blurred;
} public int Radius
{
get { return _radius; }
set
{
if (value < )
{
throw new InvalidOperationException("Radius must be greater then 0");
}
_radius = value; }
} public BlurType BlurType
{
get { return _blurType; }
set
{
_blurType = value;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging; namespace Adrian.PhotoX.Lib
{
public unsafe class RawBitmap : IDisposable
{
private Bitmap _originBitmap;
private BitmapData _bitmapData;
private byte* _begin; public RawBitmap(Bitmap originBitmap)
{
_originBitmap = originBitmap;
_bitmapData = _originBitmap.LockBits(new Rectangle(, , _originBitmap.Width, _originBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
_begin = (byte*)(void*)_bitmapData.Scan0;
} #region IDisposable Members public void Dispose()
{
_originBitmap.UnlockBits(_bitmapData);
} #endregion public unsafe byte* Begin
{
get { return _begin; }
} public unsafe byte* this[int x,int y]
{
get
{
return _begin + y * (_bitmapData.Stride) + x * ;
}
} public unsafe byte* this[int x, int y, int offset]
{
get
{
return _begin + y * (_bitmapData.Stride) + x * + offset;
}
} //public unsafe void SetColor(int x, int y, int color)
//{
// *(int*)(_begin + y * (_bitmapData.Stride) + x * 3) = color;
//} public int Stride
{
get { return _bitmapData.Stride; }
} public int Width
{
get { return _bitmapData.Width; }
} public int Height
{
get { return _bitmapData.Height; }
} public int GetOffset()
{
return _bitmapData.Stride - _bitmapData.Width * ;
} public Bitmap OriginBitmap
{
get { return _originBitmap; }
}
}
}

调用示例

            Bitmap bitmap = new Bitmap(pictureBox1.Image);
//AForge.Imaging.Filters.GaussianBlur gs = new AForge.Imaging.Filters.GaussianBlur();
//AForge.Imaging.Filters.GaussianBlur filter = new AForge.Imaging.Filters.GaussianBlur(5, 15);
//filter.ApplyInPlace(bitmap);
GaussianBlur gs = new GaussianBlur();
pictureBox2.Image = gs.ProcessImage(bitmap);

c# 高斯模糊的更多相关文章

  1. Android开发学习之路-动态高斯模糊怎么做

    什么是高斯模糊? 高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪 ...

  2. EasyPR--开发详解(3)高斯模糊、灰度化和Sobel算子

    在上篇文章中我们了解了PlateLocate的过程中的所有步骤.在本篇文章中我们对前3个步骤,分别是高斯模糊.灰度化和Sobel算子进行分析. 一.高斯模糊 1.目标 对图像去噪,为边缘检测算法做准备 ...

  3. Android 图片滤镜工具——高斯模糊

    ===================高斯模糊========================= 创建一个 ImageFilter 类(滤镜工具),代码如下: import android.graph ...

  4. .net版高斯模糊算法

    最近挺多人找高斯算法,本人贴上一个高斯模糊算法类,希望可以帮助到大家.算法的效率还是可以接受的. #region 高斯模糊算法 /// <summary> /// 高斯模糊算法 /// & ...

  5. 高斯模糊算法的 C++ 实现

    2008 年在一个 PS 讨论群里,有网友不解 Photoshop 的高斯模糊中的半径是什么含义,因此当时我写了这篇文章: 对Photoshop高斯模糊滤镜的算法总结: 在那篇文章中,主要讲解了高斯模 ...

  6. Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途

    Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途 1.1. 高斯模糊 的原理(周边像素的平均值+正态分布的权重1 1.2. 高斯模糊 的用途(磨皮,毛玻璃效果,背景虚化 ...

  7. opencv 简单模糊和高斯模糊 cvSmooth

    cv::Mat 是C++版OpenCV的新结构. cvSmooth() 是老版 C API. 没有把C接口与C + + 结合. 建议你们也可以花一些时间看一下介绍. 同样,你如果查看opencv/mo ...

  8. 半径无关单核单线程最快速高斯模糊实现(附完整C代码)

    之前,俺也发过不少快速高斯模糊算法. 俺一般认为,只要处理一千六百万像素彩色图片,在2.2GHz的CPU上单核单线程超过1秒的算法,都是不快的. 之前发的几个算法,在俺2.2GHz的CPU上耗时都会超 ...

  9. 传统高斯模糊与优化算法(附完整C++代码)

    高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次 ...

  10. iOS开发小技巧--高斯模糊框架的应用

    事件背景:彩票项目中点击检查更新之后的操作,高斯模糊效果并弹出HUD 注意:在应用别人的框架的时候,最好封装一下下. 新建一个类  继承自高斯模糊的类. 使用方法:新建一个高斯模糊类的View,添加到 ...

随机推荐

  1. [每日一题] OCP1z0-047 :2013-08-17 EXTERNAL TABLE――加载数据 ............................56

    正确答案:C 一.对答案解释: A.       TYPE:有两个选可供选择: 1.        ORACLE_LOADER:传统方式,与SQLLDR一样,参数从多,应用较多. 2.         ...

  2. [HDU 1317]XYZZY[SPFA变形][最长路]

    题意: 一个图, 点权代表走到该点可获得的能量值. 可正可负. 一个人从1 号出发,带有100点能量. 问是否有一种方案可使人在能量值>0的时候走到n. 思路: 这个题首先要注意点权. 其实就是 ...

  3. 男同胞爱小秘籍--作为爱他的女朋友了几天C规划

    各位男同胞,不知道你的女朋友没有在过去的一问天,你这个问题~~ 场景重现: 女友:"今天天气不错." 你们:"对" 女友:"今天是我们知道它的最初几天 ...

  4. Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6629298 在前面一篇文章浅谈Android系 ...

  5. 解决数据库Operation not allowed when innodb_forced_recovery > 0

    解决数据库Operation not allowed when innodb_forced_recovery > 0 请修改my.cnf innodb_force_recovery = 1 修改 ...

  6. sqlite3安装

    SQLite命令行程序(CLP)是开始使用SQLite的最好选择,按照如下步骤获取CLP: 1).打开浏览器进入SQLite主页,www.sqlite.org. 2).单击页面顶部的下载链接(Down ...

  7. IOS 开发调试方法

    0.警告 尽量一个警告都不要有 1.错误 1)红色提示 编译过不去的原因大部分是语法,检查括号的匹配,变量名称,作用域范围 2)编译可以通过,可以运行 a.运行过程中程序崩溃 在debug区域的右侧, ...

  8. Linux系统的组成和内核的组成

    关于linux的组成的宏观认识. 组成图: 内核组成: 一个完整的Linux内核一般由5部分组成,它们分别是内存管理.进程管理.进程间通信.虚拟文件系统和网络接口.

  9. WordPress插件制作教程概述

    接下来的一段时间里,开始为大家讲解WordPress插件制作系列教程,这篇主要是对WordPress插件的一些介绍和说明,还有一些我们需要注意的地方,以及需要掌握的知识. WordPress插件允许你 ...

  10. 使用jekyll和prose在github上创建博客

    利用github的pages服务可以很方便地显示和管理我们的静态页面,这样用来做博客是非常适合的. 1.首先你要有一个github的帐号 2.创建一个repo,名字叫username.github.i ...