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. vc10的C2664和C2065错误

    在vs2010中编译一个普通的C++程序(Win32 Console Application),都会出现这两个错误! 究其原因是:我们已经习惯了VC6的种种简陋和不规范! 例如,下列程序在VC6中编译 ...

  2. NYOJ130 同样的雪花 【Hash】

    同样的雪花 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描写叙述 You may have heard that no two snowflakes are alike. ...

  3. ThinkPHP实现跨模块调用操作方法概述

    ThinkPHP实现跨模块调用操作方法概述 投稿:shichen2014 字体:[增加 减小] 类型:转载   使用 $this 可以调用当前模块内的方法,但是很多情况下经常会在当前模块中调用其他模块 ...

  4. form表单提交校验

    <form id="myForm" action="http://www.365mini.com" method="post"> ...

  5. IOS开发几何类方法 CGGeometry.h文件

    CGGeometry.h文件是用C语言实现的一个封装了许多常用几何方法的文件. 一.几个常用结构体 struct CGPoint { CGFloat x; CGFloat y; }; 定义一个点,设置 ...

  6. C#总结(2)

    有输出,当然有输入.这样才会有人机交互. using System; using System.Collections.Generic; using System.Linq; using System ...

  7. ActiveMQ持久化消息(转)

    ActiveMQ的另一个问题就是只要是软件就有可能挂掉,挂掉不可怕,怕的是挂掉之后把信息给丢了,所以本节分析一下几种持久化方式: 一.持久化为文件 ActiveMQ默认就支持这种方式,只要在发消息时设 ...

  8. 01 日志组件XLog

    本文地址为:http://www.cnblogs.com/ADTL/p/5357259.html XLog为XCode的日志组件,为系统基本功能. 使用示例: 1.新建WinForm程序 2.引用Ne ...

  9. POJ 2135 Farm Tour (最小费用最大流模板)

    题目大意: 给你一个n个农场,有m条道路,起点是1号农场,终点是n号农场,现在要求从1走到n,再从n走到1,要求不走重复路径,求最短路径长度. 算法讨论: 最小费用最大流.我们可以这样建模:既然要求不 ...

  10. busybox中tftp服务器使用命令

    参数说明:-l 是local的缩写,后跟存在于Client的源文件名,或下载Client后重命名的文件名.-r 是remote的缩写,后跟Server即PC机tftp服务器根目录中的源文件名,或上传S ...