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

728x90
반응형
728x170
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

#region 중앙값 필터 적용하기 - ApplyMedianFilter(sourceBitmap, matrixSize)

/// <summary>
/// 중앙값 필터 적용하기
/// </summary>
/// <param name="sourceBitmap">소스 비트맵</param>
/// <param name="matrixSize">매트릭스 크기</param>
/// <returns>비트맵</returns>
public static Bitmap ApplyMedianFilter(Bitmap sourceBitmap, int matrixSize)
{
    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);

    int filterOffset = (matrixSize - 1) / 2;

    int temporaryOffset = 0;

    int byteOffset = 0;

    List<int> neighbourPixelList = new List<int>();

    byte[] middlePixel;

    for(int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++)
    {
        for(int offsetX = filterOffset; offsetX < sourceBitmap.Width - filterOffset; offsetX++)
        {
            byteOffset = offsetY * sourceBitmapData.Stride + offsetX * 4;

            neighbourPixelList.Clear();

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

                    neighbourPixelList.Add(BitConverter.ToInt32(sourceByteArray, temporaryOffset));
                }
            }

            neighbourPixelList.Sort();

            middlePixel = BitConverter.GetBytes(neighbourPixelList[filterOffset]);

            targetByteArray[byteOffset    ] = middlePixel[0];
            targetByteArray[byteOffset + 1] = middlePixel[1];
            targetByteArray[byteOffset + 2] = middlePixel[2];
            targetByteArray[byteOffset + 3] = middlePixel[3];
        }
    }

    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
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요