첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ BitmapHelper.cs

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

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

        #region 투명 비트맵 구하기 - GetTransparentBitmap(sourceImage, alpha)

        /// <summary>
        /// 투명 비트맵 구하기
        /// </summary>
        /// <param name="sourceImage">소스 이미지</param>
        /// <param name="alpha">알파</param>
        /// <returns>투명 비트맵</returns>
        public static Bitmap GetTransparentBitmap(Image sourceImage, byte alpha = 100)
        {
            Bitmap targetBitmap = GetBitmap(sourceImage);

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

            IntPtr sourceHandle = targetBitmapData.Scan0;

            byte[] targetByteArray = new byte[targetBitmapData.Stride * targetBitmap.Height];

            Marshal.Copy(sourceHandle, targetByteArray, 0, targetByteArray.Length);

            for(int i = 3; i < targetByteArray.Length; i += 4)
            {
                targetByteArray[i] = alpha;
            }

            Marshal.Copy(targetByteArray, 0, sourceHandle, targetByteArray.Length);

            targetBitmap.UnlockBits(targetBitmapData);

            targetBitmapData = null;
            targetByteArray  = null;

            return targetBitmap;
        }

        #endregion
        #region 회색조 비트맵 구하기 - GetGrayscaleBitmap(sourceImage)

        /// <summary>
        /// 회색조 비트맵 구하기
        /// </summary>
        /// <param name="sourceImage">소스 이미지</param>
        /// <returns>회색조 비트맵</returns>
        public static Bitmap GetGrayscaleBitmap(Image sourceImage)
        {
            Bitmap targetBitmap = GetBitmap(sourceImage);

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

            IntPtr sourceHandle = targetBitmapData.Scan0;

            byte[] targetByteArray = new byte[targetBitmapData.Stride * targetBitmap.Height];

            Marshal.Copy(sourceHandle, targetByteArray, 0, targetByteArray.Length);

            float rgb = 0;

            for(int i = 0; i < targetByteArray.Length; i += 4)
            {
                rgb =  targetByteArray[i    ] * 0.11f;
                rgb += targetByteArray[i + 1] * 0.59f;
                rgb += targetByteArray[i + 2] * 0.3f;

                targetByteArray[i    ] = (byte)rgb;
                targetByteArray[i + 1] = targetByteArray[i];
                targetByteArray[i + 2] = targetByteArray[i];

                targetByteArray[i + 3] = 255;
            }

            Marshal.Copy(targetByteArray, 0, sourceHandle, targetByteArray.Length);

            targetBitmap.UnlockBits(targetBitmapData);

            targetBitmapData = null;
            targetByteArray  = null;

            return targetBitmap;
        }

        #endregion
        #region 네거티브 비트맵 구하기 - GetNegativeBitmap(sourceImage)

        /// <summary>
        /// 네거티브 비트맵 구하기
        /// </summary>
        /// <param name="sourceImage">소스 이미지</param>
        /// <returns>네거티브 비트맵</returns>
        public static Bitmap GetNegativeBitmap(Image sourceImage)
        {
            Bitmap targetBitmap = GetBitmap(sourceImage);

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

            IntPtr sourceHandle = targetBitmapData.Scan0;

            byte[] targetByteArray = new byte[targetBitmapData.Stride * targetBitmap.Height];

            Marshal.Copy(sourceHandle, targetByteArray, 0, targetByteArray.Length);

            byte[] pixelByteArray = null;

            int pixel = 0;

            for(int i = 0; i < targetByteArray.Length; i += 4)
            {
                pixel = ~BitConverter.ToInt32(targetByteArray, i);

                pixelByteArray = BitConverter.GetBytes(pixel);

                targetByteArray[i    ] = pixelByteArray[0];
                targetByteArray[i + 1] = pixelByteArray[1];
                targetByteArray[i + 2] = pixelByteArray[2];
            }

            Marshal.Copy(targetByteArray, 0, sourceHandle, targetByteArray.Length);

            targetBitmap.UnlockBits(targetBitmapData);

            targetBitmapData = null;
            targetByteArray  = null;

            return targetBitmap;
        }

        #endregion
        #region 세피아 톤 비트맵 구하기 - GetSepiaToneBitmap(sourceImage)

        /// <summary>
        /// 세피아 톤 비트맵 구하기
        /// </summary>
        /// <param name="sourceImage">소스 이미지</param>
        /// <returns>세피아 톤 비트맵</returns>
        public static Bitmap GetSepiaToneBitmap(Image sourceImage)
        {
            Bitmap targetBitmap = GetBitmap(sourceImage);

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

            IntPtr sourceHandle = targetBitmapData.Scan0;

            byte[] targetByteArray = new byte[targetBitmapData.Stride * targetBitmap.Height];

            Marshal.Copy(sourceHandle, targetByteArray, 0, targetByteArray.Length);

            byte maximumValue = 255;

            float red   = 0;
            float green = 0;
            float blue  = 0;

            for(int i = 0; i < targetByteArray.Length; i += 4)
            {
                red   = targetByteArray[i] * 0.189f + targetByteArray[i + 1] * 0.769f + targetByteArray[i + 2] * 0.393f;
                green = targetByteArray[i] * 0.168f + targetByteArray[i + 1] * 0.686f + targetByteArray[i + 2] * 0.349f;
                blue  = targetByteArray[i] * 0.131f + targetByteArray[i + 1] * 0.534f + targetByteArray[i + 2] * 0.272f;

                targetByteArray[i + 2] = (red   > maximumValue ? maximumValue : (byte)red  );
                targetByteArray[i + 1] = (green > maximumValue ? maximumValue : (byte)green);
                targetByteArray[i    ] = (blue  > maximumValue ? maximumValue : (byte)blue );
            }

            Marshal.Copy(targetByteArray, 0, sourceHandle, targetByteArray.Length);

            targetBitmap.UnlockBits(targetBitmapData);

            targetBitmapData = null;
            targetByteArray  = null;

            return targetBitmap;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private

        #region 비트맵 구하기 - GetBitmap(sourceImage)

        /// <summary>
        /// 비트맵 구하기
        /// </summary>
        /// <param name="sourceImage">소스 이미지</param>
        /// <returns>비트맵</returns>
        private static Bitmap GetBitmap(Image sourceImage)
        {
            Bitmap targetBitmap = new Bitmap
            (
                sourceImage.Width,
                sourceImage.Height,
                PixelFormat.Format32bppArgb
            );

            using(Graphics graphics = Graphics.FromImage(targetBitmap))
            {
                graphics.DrawImage
                (
                    sourceImage,
                    new Rectangle(0, 0, targetBitmap.Width, targetBitmap.Height),
                    new Rectangle(0, 0, targetBitmap.Width, targetBitmap.Height),
                    GraphicsUnit.Pixel
                );

                graphics.Flush();
            }

            return targetBitmap;
        }

        #endregion
    }
}

 

728x90

 

▶ MainForm.cs

using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            this.loadImageButton.Click                       += loadImageButton_Click;
            this.grayscaleImageRadioButton.CheckedChanged    += imageRadioButton_CheckedChanged;
            this.transparencyImageRadioButton.CheckedChanged += imageRadioButton_CheckedChanged;
            this.negativeImageRadioButton.CheckedChanged     += imageRadioButton_CheckedChanged;
            this.sepiaToneImageRadioButton.CheckedChanged    += imageRadioButton_CheckedChanged;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 이미지 로드 버튼 클릭시 처리하기 - loadImageButton_Click(sender, e)

        /// <summary>
        /// 이미지 로드 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void loadImageButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Title  = "이미지 파일 선택하기";
            openFileDialog.Filter = "Png files (*.png)|*.png|Bitmap files (*.bmp)|*.bmp|Jpeg files (*.jpg)|*.jpg";

            if(openFileDialog.ShowDialog() == DialogResult.OK)
            {
                StreamReader streamReader = new StreamReader(openFileDialog.FileName);

                Bitmap sourceBitmap = (Bitmap)Bitmap.FromStream(streamReader.BaseStream);

                streamReader.Close();

                this.inputImagePanel.BackgroundImage = sourceBitmap;

                imageRadioButton_CheckedChanged(sender, e);
            }
        }

        #endregion
        #region 이미지 라디오 버튼 클릭시 처리하기 - imageRadioButton_CheckedChanged(sender, e)

        /// <summary>
        /// 이미지 라디오 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void imageRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            if(this.inputImagePanel.BackgroundImage != null)
            {
                if(this.grayscaleImageRadioButton.Checked == true)
                {
                    this.outputImagePanel.BackgroundImage = BitmapHelper.GetGrayscaleBitmap(this.inputImagePanel.BackgroundImage);
                }
                else if(this.transparencyImageRadioButton.Checked == true)
                {
                    this.outputImagePanel.BackgroundImage = BitmapHelper.GetTransparentBitmap(this.inputImagePanel.BackgroundImage);
                }
                else if(this.negativeImageRadioButton.Checked == true)
                {
                    this.outputImagePanel.BackgroundImage = BitmapHelper.GetNegativeBitmap(this.inputImagePanel.BackgroundImage);
                }
                else if(this.sepiaToneImageRadioButton.Checked == true)
                {
                    this.outputImagePanel.BackgroundImage = BitmapHelper.GetSepiaToneBitmap(this.inputImagePanel.BackgroundImage);
                }
            }
        }

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

댓글을 달아 주세요