첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.

728x90
반응형
728x170

■ Bitmap 클래스 : 회선 필터(Convolution Filter) 사용하기 예제

using System.Drawing;

...

Bitmap sourceBitmap;

...

Bitmap targetBitmap = BitmapHelper.ApplyConvolutionFilter(sourceBitmap, Matrix.GaussianBlur3x3);

 

728x90

 

■ Bitmap 클래스 : 회선 필터(Convolution Filter) 사용하기

 

▶ BitmapHelper.cs

using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace TestProject
{
    /// <summary>
    /// 비트맵 헬퍼
    /// </summary>
    public static class BitmapHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 회선 필터 적용하기 - ApplyConvolutionFilter(sourceBitmap, filterArray, factor, bias)

        /// <summary>
        /// 회선 필터 적용하기
        /// </summary>
        /// <param name="sourceBitmap">소스 비트맵</param>
        /// <param name="filterArray">필터 배열</param>
        /// <param name="factor">인자</param>
        /// <param name="bias">바이어스</param>
        /// <returns>비트맵</returns>
        public static Bitmap ApplyConvolutionFilter(Bitmap sourceBitmap, double[,] filterArray, double factor = 1, int bias = 0)
        {
            BitmapData sourceBitmapData = sourceBitmap.LockBits
            (
                new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb
            );

            byte[] sourceByteArray = new byte[sourceBitmapData.Stride * sourceBitmapData.Height];
            byte[] targetByteArray = new byte[sourceBitmapData.Stride * sourceBitmapData.Height];

            Marshal.Copy(sourceBitmapData.Scan0, sourceByteArray, 0, sourceByteArray.Length);

            sourceBitmap.UnlockBits(sourceBitmapData);

            double blue  = 0.0;
            double green = 0.0;
            double red   = 0.0;

            int filterWidth  = filterArray.GetLength(1);
            int filterHeight = filterArray.GetLength(0);
            int filterOffset = (filterWidth - 1) / 2;
            int sourceOffset = 0;
            int targetOffset = 0;

            for(int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++)
            {
                for(int offsetX = filterOffset; offsetX < sourceBitmap.Width - filterOffset; offsetX++)
                {
                    blue  = 0;
                    green = 0;
                    red   = 0;

                    targetOffset = offsetY * sourceBitmapData.Stride + offsetX * 4;

                    for(int filterY = -filterOffset; filterY <= filterOffset; filterY++)
                    {
                        for(int filterX = -filterOffset; filterX <= filterOffset; filterX++)
                        {
                            sourceOffset = targetOffset + (filterX * 4) + (filterY * sourceBitmapData.Stride);

                            blue += (double)(sourceByteArray[sourceOffset]) * 
                                    filterArray[filterY + filterOffset, filterX + filterOffset];

                            green += (double)(sourceByteArray[sourceOffset + 1]) *
                                        filterArray[filterY + filterOffset, filterX + filterOffset];

                            red += (double)(sourceByteArray[sourceOffset + 2]) *
                                    filterArray[filterY + filterOffset, filterX + filterOffset];
                        }
                    }

                    blue  = factor * blue + bias;
                    green = factor * green + bias;
                    red   = factor * red + bias;

                    blue  = (blue  > 255 ? 255 : (blue  < 0 ? 0 : blue ));
                    green = (green > 255 ? 255 : (green < 0 ? 0 : green));
                    red   = (red   > 255 ? 255 : (red   < 0 ? 0 : red  ));

                    targetByteArray[targetOffset    ] = (byte)(blue);
                    targetByteArray[targetOffset + 1] = (byte)(green);
                    targetByteArray[targetOffset + 2] = (byte)(red);
                    targetByteArray[targetOffset + 3] = 255;
                }
            }

            Bitmap targetBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height);

            BitmapData targetBitmapData = targetBitmap.LockBits
            (
                new Rectangle(0, 0, targetBitmap.Width, targetBitmap.Height),
                ImageLockMode.WriteOnly,
                PixelFormat.Format32bppArgb
            );

            Marshal.Copy(targetByteArray, 0, targetBitmapData.Scan0, targetByteArray.Length);

            targetBitmap.UnlockBits(targetBitmapData);

            return targetBitmap;
        }

        #endregion
    }  
}

 

300x250

 

▶ Matrix.cs

namespace TestProject
{
    /// <summary>
    /// 매트릭스
    /// </summary>
    public static class Matrix
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region MEAN 3X3 - Mean3X3

        /// <summary>
        /// MEAN 3X3
        /// </summary>
        public static double[,] Mean3X3
        {
            get
            {
                return new double[,]
                {
                    { 1, 1, 1, }, 
                    { 1, 1, 1, }, 
                    { 1, 1, 1, }
                };
            }
        }

        #endregion
        #region MEAN 5X5 - Mean5X5

        /// <summary>
        /// MEAN 5X5
        /// </summary>
        public static double[,] Mean5X5
        {
            get
            {
                return new double[,]
                {
                    { 1, 1, 1, 1, 1 }, 
                    { 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 }
                };
            }
        }

        #endregion
        #region MEAN 7X7 - Mean7X7

        /// <summary>
        /// MEAN 7X7
        /// </summary>
        public static double[,] Mean7X7
        {
            get
            {
                return new double[,]
                {
                    { 1, 1, 1, 1, 1, 1, 1 }, 
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                };
            }
        }

        #endregion
        #region MEAN 9X9 - Mean9X9

        /// <summary>
        /// MEAN 9X9
        /// </summary>
        public static double[,] Mean9X9
        {
            get
            {
                return new double[,]
                {
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 }
                };
            }
        }

        #endregion
        #region GAUSSIAN BLUR 3X3 - GaussianBlur3X3

        /// <summary>
        /// GAUSSIAN BLUR 3X3
        /// </summary>
        public static double[,] GaussianBlur3X3
        {
            get
            {
                return new double[,]
                {
                    { 1, 2, 1, }, 
                    { 2, 4, 2, }, 
                    { 1, 2, 1, }
                };
            }
        }

        #endregion
        #region GAUSSIAN BLUR 5X5 - GaussianBlur5X5

        /// <summary>
        /// GAUSSIAN BLUR 5X5
        /// </summary>
        public static double[,] GaussianBlur5X5
        {
            get
            {
                return new double[,]
                {
                    { 2, 04, 05, 04, 2 }, 
                    { 4, 09, 12, 09, 4 }, 
                    { 5, 12, 15, 12, 5 },
                    { 4, 09, 12, 09, 4 },
                    { 2, 04, 05, 04, 2 }
                };
            }
        }

        #endregion
        #region MOTION BLUR 5X5 - MotionBlur5X5

        /// <summary>
        /// MOTION BLUR 5X5
        /// </summary>
        public static double[,] MotionBlur5X5
        {
            get
            {
                return new double[,]
                {
                    { 1, 0, 0, 0, 1 }, 
                    { 0, 1, 0, 1, 0 }, 
                    { 0, 0, 1, 0, 0 },
                    { 0, 1, 0, 1, 0 },
                    { 1, 0, 0, 0, 1 }
                };
            }
        }

        #endregion
        #region MOTION BLUR 5X5 AT 45 DEGREES - MotionBlur5X5At45Degrees

        /// <summary>
        /// MOTION BLUR 5X5 AT 45 DEGREES
        /// </summary>
        public static double[,] MotionBlur5X5At45Degrees
        {
            get
            {
                return new double[,]
                {
                    { 0, 0, 0, 0, 1 }, 
                    { 0, 0, 0, 1, 0 }, 
                    { 0, 0, 1, 0, 0 },
                    { 0, 1, 0, 0, 0 },
                    { 1, 0, 0, 0, 0 }
                };
            }
        }

        #endregion
        #region MOTION BLUR 5X5 AT 135 DEGREES - MotionBlur5X5At135Degrees

        /// <summary>
        /// MOTION BLUR 5X5 AT 135 DEGREES
        /// </summary>
        public static double[,] MotionBlur5X5At135Degrees
        {
            get
            {
                return new double[,]
                {
                    { 1, 0, 0, 0, 0 }, 
                    { 0, 1, 0, 0, 0 }, 
                    { 0, 0, 1, 0, 0 },
                    { 0, 0, 0, 1, 0 },
                    { 0, 0, 0, 0, 1 }
                };
            }
        }

        #endregion
        #region MOTION BLUR 7X7 - MotionBlur7X7

        /// <summary>
        /// MOTION BLUR 7X7
        /// </summary>
        public static double[,] MotionBlur7X7
        {
            get
            {
                return new double[,]
                {
                    { 1, 0, 0, 0, 0, 0, 1 }, 
                    { 0, 1, 0, 0, 0, 1, 0 }, 
                    { 0, 0, 1, 0, 1, 0, 0 },
                    { 0, 0, 0, 1, 0, 0, 0 },
                    { 0, 0, 1, 0, 1, 0, 0 },
                    { 0, 1, 0, 0, 0, 1, 0 },
                    { 1, 0, 0, 0, 0, 0, 1 }
                };
            }
        }

        #endregion
        #region MOTION BLUR 7X7 AT 45 DEGREES - MotionBlur7X7At45Degrees

        /// <summary>
        /// MOTION BLUR 7X7 AT 45 DEGREES
        /// </summary>
        public static double[,] MotionBlur7X7At45Degrees
        {
            get
            {
                return new double[,]
                {
                    { 0, 0, 0, 0, 0, 0, 1 }, 
                    { 0, 0, 0, 0, 0, 1, 0 }, 
                    { 0, 0, 0, 0, 1, 0, 0 },
                    { 0, 0, 0, 1, 0, 0, 0 },
                    { 0, 0, 1, 0, 0, 0, 0 },
                    { 0, 1, 0, 0, 0, 0, 0 },
                    { 1, 0, 0, 0, 0, 0, 0 }
                };
            }
        }

        #endregion
        #region MOTION BLUR 7X7 AT 135 DEGREES - MotionBlur7X7At135Degrees

        /// <summary>
        /// MOTION BLUR 7X7 AT 135 DEGREES
        /// </summary>
        public static double[,] MotionBlur7X7At135Degrees
        {
            get
            {
                return new double[,]
                {
                    { 1, 0, 0, 0, 0, 0, 0 }, 
                    { 0, 1, 0, 0, 0, 0, 0 }, 
                    { 0, 0, 1, 0, 0, 0, 0 },
                    { 0, 0, 0, 1, 0, 0, 0 },
                    { 0, 0, 0, 0, 1, 0, 0 },
                    { 0, 0, 0, 0, 0, 1, 0 },
                    { 0, 0, 0, 0, 0, 0, 1 }
                };
            }
        }

        #endregion
        #region MOTION BLUR 9X9 - MotionBlur9X9

        /// <summary>
        /// MOTION BLUR 9X9
        /// </summary>
        public static double[,] MotionBlur9X9
        {
            get
            {
                return new double[,]
                {
                    { 1, 0, 0, 0, 0, 0, 0, 0, 1 },
                    { 0, 1, 0, 0, 0, 0, 0, 1, 0 },
                    { 0, 0, 1, 0, 0, 0, 1, 0, 0 },
                    { 0, 0, 0, 1, 0, 1, 0, 0, 0 },
                    { 0, 0, 0, 0, 1, 0, 0, 0, 0 },
                    { 0, 0, 0, 1, 0, 1, 0, 0, 0 },
                    { 0, 0, 1, 0, 0, 0, 1, 0, 0 },
                    { 0, 1, 0, 0, 0, 0, 0, 1, 0 },
                    { 1, 0, 0, 0, 0, 0, 0, 0, 1 }
                };
            }
        }

        #endregion
        #region MOTION BLUR 9X9 AT 45 DEGREES - MotionBlur9X9At45Degrees

        /// <summary>
        /// MOTION BLUR 9X9 AT 45 DEGREES
        /// </summary>
        public static double[,] MotionBlur9X9At45Degrees
        {
            get
            {
                return new double[,]
                {
                    { 0, 0, 0, 0, 0, 0, 0, 0, 1 },
                    { 0, 0, 0, 0, 0, 0, 0, 1, 0 },
                    { 0, 0, 0, 0, 0, 0, 1, 0, 0 },
                    { 0, 0, 0, 0, 0, 1, 0, 0, 0 },
                    { 0, 0, 0, 0, 1, 0, 0, 0, 0 },
                    { 0, 0, 0, 1, 0, 0, 0, 0, 0 },
                    { 0, 0, 1, 0, 0, 0, 0, 0, 0 },
                    { 0, 1, 0, 0, 0, 0, 0, 0, 0 },
                    { 1, 0, 0, 0, 0, 0, 0, 0, 0 }
                };
            }
        }

        #endregion
        #region MOTION BLUR 9X9 AT 135 DEGREES - MotionBlur9X9At135Degrees

        /// <summary>
        /// MOTION BLUR 9X9 AT 135 DEGREES
        /// </summary>
        public static double[,] MotionBlur9X9At135Degrees
        {
            get
            {
                return new double[,]
                {
                    { 1, 0, 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 1, 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 0, 1, 0, 0, 0, 0, 0, 0 },
                    { 0, 0, 0, 1, 0, 0, 0, 0, 0 },
                    { 0, 0, 0, 0, 1, 0, 0, 0, 0 },
                    { 0, 0, 0, 0, 0, 1, 0, 0, 0 },
                    { 0, 0, 0, 0, 0, 0, 1, 0, 0 },
                    { 0, 0, 0, 0, 0, 0, 0, 1, 0 },
                    { 0, 0, 0, 0, 0, 0, 0, 0, 1 }
                };
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요