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. java与.net比较学习系列(7) 属性

    文章摘自:http://www.cnblogs.com/mcgrady/p/3411405.html 说起属性,实际上java中没有属性这个概念,只有字段和方法,但是可以通过私有字段和声明get,se ...

  2. 初步swift语言学习笔记9(OC与Swift杂)

    笔者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/34440159 转载请注明出处 假设认为文章对你有所帮助,请通过留言 ...

  3. 原生Javascript实现图片轮播效果

    首先引入js运动框架 function getStyle(obj,name){ if(obj.currentStyle){ return obj.currentStyle[name]; } else{ ...

  4. Sql server Lock

    http://www.cnblogs.com/wuyifu/archive/2013/11/28/3447870.html

  5. PL/SQL文档

    http://www.oracle.com/technetwork/database/features/plsql/index.html 注册表学习 http://itlab.idcquan.com/ ...

  6. 配置IIS

    1.aspnet_regiis -i 重新安装IIs  vs2013的命令符 2. 分配权限 1.对文件夹,权限,安全,分配权限 2.设置webconfig 对应的httpModel 及安全性 3.设 ...

  7. 子元素用margin-top 为什么反而作用在父元素上?对使用margin-top 的元素本身不起作用?

    在这个说明中,“collapsing margins”(折叠margin)的意思是:2个或以上盒模型之间(关系可以是相邻或嵌套)相邻的margin属性(这之间不能有非空内容.padding区域.bor ...

  8. spring3+hibernate3+(dbcp+oracle+拦截器事务配置)整合(一)

    1.applicationContext-base.xml文件 <?xml version="1.0" encoding="UTF-8"?>< ...

  9. php getenv 和 putenv 用法

    getenv 的功能是取得一个指定的环境变量. getenv('REMOTE_ADDR') 和 $_SERVER['REMOTE_ADDR'] 功能一样 但是当Web服务器API是ASAPI (IIS ...

  10. typecho博客出404页面修改方法

    适用于typecho博客版本为:0.9 (13.12.12) typecho博客,很多时候可能安装完毕,除了首页,其他页面都是404=.= 在匹配*.php的location区域修改为以下格式: lo ...