• c# 高斯模糊


    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 = 1;
            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 * 2 + 1;
                _kernel = new int[sz];
                _multable = new int[sz, 256];
                for (int i = 1; i <= _radius; i++)
                {
                    int szi = _radius - i;
                    int szj = _radius + i;
                    _kernel[szj] = _kernel[szi] = (szi + 1) * (szi + 1);
                    _kernelSum += (_kernel[szj] + _kernel[szi]);
                    for (int j = 0; j < 256; j++)
                    {
                        _multable[szj, j] = _multable[szi, j] = _kernel[szj] * j;
                    }
                }
                _kernel[_radius] = (_radius + 1) * (_radius + 1);
                _kernelSum += _kernel[_radius];
                for (int j = 0; j < 256; 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 = 0;
                        unsafe
                        {
                            //sw.Reset();
                            //sw.Start();
    
                            byte* ptr = src.Begin;
                            for (int i = 0; i < src.Height; i++)
                            {
                                for (int j = 0; 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 = 0;
                            index = 0;
    
                            //sw.Reset();
                            //sw.Start();
    
                            if (_blurType != BlurType.VerticalOnly)
                            {
                                for (int i = 0; i < src.Height; i++)
                                {
                                    for (int j = 0; j < src.Width; j++)
                                    {
                                        bsum = gsum = rsum = 0;
                                        read = index - _radius;
    
                                        for (int z = 0; 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 - 1)
                                            {
                                                int idx = start + src.Width - 1;
                                                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 = 0; i < src.Height; i++)
                            {
                                int y = i - _radius;
                                start = y * src.Width;
                                for (int j = 0; j < src.Width; j++)
                                {
                                    bsum = gsum = rsum = 0;
                                    read = start + j;
                                    tempy = y;
                                    for (int z = 0; 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 < 0)
                                            {
                                                bsum += _multable[z, b[j]];
                                                gsum += _multable[z, g[j]];
                                                rsum += _multable[z, r[j]];
                                            }
                                            else if (tempy > src.Height - 1)
                                            {
                                                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 < 0)
                                            {
                                                bsum += _multable[z, b2[j]];
                                                gsum += _multable[z, g2[j]];
                                                rsum += _multable[z, r2[j]];
                                            }
                                            else if (tempy > src.Height - 1)
                                            {
                                                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[0] = (byte)(bsum / _kernelSum);
                                    pcell[1] = (byte)(gsum / _kernelSum);
                                    pcell[2] = (byte)(rsum / _kernelSum);
                                }
                            }
                            //sw.Stop();
                            //t4 = sw.ElapsedMilliseconds;
                        }
                    }
                }
    
                return blurred;
            }
    
            public int Radius
            {
                get { return _radius; }
                set
                {
                    if (value < 1)
                    {
                        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(0, 0, _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 * 3;
                }
            }
    
            public unsafe byte* this[int x, int y, int offset]
            {
                get
                {
                    return _begin + y * (_bitmapData.Stride) + x * 3 + 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 * 3;
            }
    
            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(15);
                pictureBox2.Image = gs.ProcessImage(bitmap); 
  • 相关阅读:
    C#(16进制数据之间的转换)
    解决windows7您当前无权访问该文件夹的问题
    获取本周的周一和周日
    在GridView中使用Cache
    在C#中完成海量数据的批量插入和更新
    母版页中对控件ID的处理
    PostgreSQL函数和运算符(二)
    js检查首字符是否是英文字符
    Asp.net Ajax实现拖放实战
    js移除数组中指导位置元素
  • 原文地址:https://www.cnblogs.com/yeye518/p/4161141.html
Copyright © 2020-2023  润新知