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

TestProject.zip
0.02MB

▶ ColorComponentBlendType.cs

namespace TestProject
{
    /// <summary>
    /// 색상 컴포넌트 블렌드 타입
    /// </summary>
    public enum ColorComponentBlendType
    {
        /// <summary>
        /// 가산
        /// </summary>
        Add,

        /// <summary>
        /// 감산
        /// </summary>
        Subtract,

        /// <summary>
        /// 평균
        /// </summary>
        Average,

        /// <summary>
        /// 내림차순
        /// </summary>
        DescendingOrder,

        /// <summary>
        /// 올림차순
        /// </summary>
        AscendingOrder
    }
}

 

728x90

 

▶ BitmapFilterData.cs

using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace TestProject
{
    /// <summary>
    /// 비트맵 필터 데이터
    /// </summary>
    [Serializable]
    public class BitmapFilterData
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 소스 청색 이용 가능 여부
        /// </summary>
        private bool sourceBlueEnabled = false;

        /// <summary>
        /// 소스 녹색 이용 가능 여부
        /// </summary>
        private bool sourceGreenEnabled = false;

        /// <summary>
        /// 소스 적색 이용 가능 여부
        /// </summary>
        private bool sourceRedEnabled = false;

        /// <summary>
        /// 소스 청색 레벨
        /// </summary>
        private float sourceBlueLevel = 1.0f;

        /// <summary>
        /// 소스 녹색 레벨
        /// </summary>
        private float sourceGreenLevel = 1.0f;

        /// <summary>
        /// 소스 적색 레벨
        /// </summary>
        private float sourceRedLevel = 1.0f;

        /// <summary>
        /// 오버레이 청색 이용 가능 여부
        /// </summary>
        private bool overlayBlueEnabled = false;

        /// <summary>
        /// 오버레이 녹색 이용 가능 여부
        /// </summary>
        private bool overlayGreenEnabled = false;

        /// <summary>
        /// 오버레이 적색 이용 가능 여부
        /// </summary>
        private bool overlayRedEnabled = false;

        /// <summary>
        /// 오버레이 청색 레벨
        /// </summary>
        private float overlayBlueLevel = 0.0f;

        /// <summary>
        /// 오버레이 녹색 레벨
        /// </summary>
        private float overlayGreenLevel = 0.0f;

        /// <summary>
        /// 오버레이 적색 레벨
        /// </summary>
        private float overlayRedLevel = 0.0f;

        /// <summary>
        /// 블렌드 타입 청색
        /// </summary>
        private ColorComponentBlendType blendTypeBlue = ColorComponentBlendType.Add;

        /// <summary>
        /// 블렌드 타입 녹색
        /// </summary>
        private ColorComponentBlendType blendTypeGreen = ColorComponentBlendType.Add;

        /// <summary>
        /// 블렌드 타입 적색
        /// </summary>
        private ColorComponentBlendType blendTypeRed = ColorComponentBlendType.Add;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 소스 청색 이용 가능 여부 - SourceBlueEnabled

        /// <summary>
        /// 소스 청색 이용 가능 여부
        /// </summary>
        public bool SourceBlueEnabled
        {
            get
            {
                return this.sourceBlueEnabled;
            }
            set
            {
                this.sourceBlueEnabled = value;
            }
        }

        #endregion
        #region 소스 녹색 이용 가능 여부 - SourceGreenEnabled

        /// <summary>
        /// 소스 녹색 이용 가능 여부
        /// </summary>
        public bool SourceGreenEnabled
        {
            get
            {
                return this.sourceGreenEnabled;
            }
            set
            {
                this.sourceGreenEnabled = value;
            }
        }

        #endregion 소스 적색 이용 가능 여부 - 
        #region 소스 적색 이용 가능 여부 - SourceRedEnabled

        /// <summary>
        /// 소스 적색 이용 가능 여부
        /// </summary>
        public bool SourceRedEnabled
        {
            get
            {
                return this.sourceRedEnabled;
            }
            set
            {
                this.sourceRedEnabled = value;
            }
        }

        #endregion
        #region 소스 청색 레벨 - SourceBlueLevel

        /// <summary>
        /// 소스 청색 레벨
        /// </summary>
        public float SourceBlueLevel
        {
            get
            {
                return this.sourceBlueLevel;
            }
            set
            {
                this.sourceBlueLevel = value;
            }
        }

        #endregion
        #region 소스 녹색 레벨 - SourceGreenLevel

        /// <summary>
        /// 소스 녹색 레벨
        /// </summary>
        public float SourceGreenLevel
        {
            get
            {
                return this.sourceGreenLevel;
            }
            set
            {
                this.sourceGreenLevel = value;
            }
        }

        #endregion
        #region 소스 적색 레벨 - SourceRedLevel

        /// <summary>
        /// 소스 적색 레벨
        /// </summary>
        public float SourceRedLevel
        {
            get
            {
                return this.sourceRedLevel;
            }
            set
            {
                this.sourceRedLevel = value;
            }
        }

        #endregion
        #region 오버레이 청색 이용 가능 여부 - OverlayBlueEnabled

        /// <summary>
        /// 오버레이 청색 이용 가능 여부
        /// </summary>
        public bool OverlayBlueEnabled
        {
            get
            {
                return this.overlayBlueEnabled;
            }
            set
            {
                this.overlayBlueEnabled = value;
            }
        }

        #endregion
        #region 오버레이 녹색 이용 가능 여부 - OverlayGreenEnabled

        /// <summary>
        /// 오버레이 녹색 이용 가능 여부
        /// </summary>
        public bool OverlayGreenEnabled
        {
            get
            {
                return this.overlayGreenEnabled;
            }
            set
            {
                this.overlayGreenEnabled = value;
            }
        }

        #endregion
        #region 오버레이 적색 이용 가능 여부 - OverlayRedEnabled

        /// <summary>
        /// 오버레이 적색 이용 가능 여부
        /// </summary>
        public bool OverlayRedEnabled
        {
            get
            {
                return this.overlayRedEnabled;
            }
            set
            {
                this.overlayRedEnabled = value;
            }
        }

        #endregion
        #region 오버레이 청색 레벨 - OverlayBlueLevel

        /// <summary>
        /// 오버레이 청색 레벨
        /// </summary>
        public float OverlayBlueLevel
        {
            get
            {
                return this.overlayBlueLevel;
            }
            set
            {
                this.overlayBlueLevel = value;
            }
        }

        #endregion
        #region 오버레이 녹색 레벨 - OverlayGreenLevel

        /// <summary>
        /// 오버레이 녹색 레벨
        /// </summary>
        public float OverlayGreenLevel
        {
            get
            {
                return this.overlayGreenLevel;
            }
            set
            {
                this.overlayGreenLevel = value;
            }
        }

        #endregion
        #region 오버레이 적색 레벨 - OverlayRedLevel

        /// <summary>
        /// 오버레이 적색 레벨
        /// </summary>
        public float OverlayRedLevel
        {
            get
            {
                return this.overlayRedLevel;
            }
            set
            {
                this.overlayRedLevel = value;
            }
        }

        #endregion
        #region 블렌드 타입 청색 - BlendTypeBlue

        /// <summary>
        /// 블렌드 타입 청색
        /// </summary>
        public ColorComponentBlendType BlendTypeBlue
        {
            get
            {
                return this.blendTypeBlue;
            }
            set
            {
                this.blendTypeBlue = value;
            }
        }

        #endregion
        #region 블렌드 타입 녹색 - BlendTypeGreen

        /// <summary>
        /// 블렌드 타입 녹색
        /// </summary>
        public ColorComponentBlendType BlendTypeGreen
        {
            get
            {
                return this.blendTypeGreen;
            }
            set
            {
                this.blendTypeGreen = value;
            }
        }

        #endregion
        #region 블렌드 타입 적색 - BlendTypeRed

        /// <summary>
        /// 블렌드 타입 적색
        /// </summary>
        public ColorComponentBlendType BlendTypeRed
        {
            get
            {
                return this.blendTypeRed;
            }
            set
            {
                this.blendTypeRed = value;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 직렬화하기 - Serialize(filterData)

        /// <summary>
        /// 직렬화하기
        /// </summary>
        /// <param name="filterData">비트맵 필터 데이터</param>
        /// <returns>XML 문자열</returns>
        public static string Serialize(BitmapFilterData filterData)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(BitmapFilterData));

            XmlWriterSettings settings = new XmlWriterSettings();

            settings.Encoding = Encoding.UTF8;
            settings.Indent   = true;

            MemoryStream memoryStream = new MemoryStream();

            XmlWriter writer = XmlWriter.Create(memoryStream, settings);

            serializer.Serialize(writer, filterData);

            writer.Flush();

            string xmlString = settings.Encoding.GetString(memoryStream.ToArray());
            
            writer.Close();

            memoryStream.Close();
            memoryStream.Dispose();

            return xmlString;
        }

        #endregion
        #region 역직렬화하기 - Deserialize(xmlString)

        /// <summary>
        /// 역직렬화하기
        /// </summary>
        /// <param name="xmlString">XML 문자열</param>
        /// <returns>비트맵 필터 데이터</returns>
        public static BitmapFilterData Deserialize(string xmlString)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(BitmapFilterData));

            MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString));

            XmlReader reader = XmlReader.Create(memoryStream);

            BitmapFilterData filterData = null;

            if(serializer.CanDeserialize(reader) == true)
            {
                reader.Close();

                memoryStream.Position = 0;

                filterData = (BitmapFilterData)serializer.Deserialize(memoryStream);
            }

            memoryStream.Close();
            memoryStream.Dispose();

            return filterData;
        }

        #endregion
    }
}

 

300x250

 

▶ BitmapHelper.cs

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;

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

        #region 비트맵 구하기 - GetBitmap(filePath, bitmapSize)

        /// <summary>
        /// 비트맵 구하기
        /// </summary>
        /// <param name="filePath">파일 경로</param>
        /// <param name="bitmapSize">비트맵 크기</param>
        /// <returns>비트맵</returns>
        public static Bitmap GetBitmap(string filePath, Size? bitmapSize = null)
        {
            StreamReader streamReader = new StreamReader(filePath);

            Bitmap bitmap = Bitmap.FromStream(streamReader.BaseStream) as Bitmap;

            streamReader.Close();

            int width  = bitmap.Width;
            int height = bitmap.Height;

            if(bitmapSize != null)
            {
                width  = bitmapSize.Value.Width;
                height = bitmapSize.Value.Height;
            }

            if(bitmap.PixelFormat != PixelFormat.Format32bppArgb || bitmap.Width != width || bitmap.Height != height)
            {
                bitmap = GetBitmap(bitmap, width, height);
            }

            return bitmap;
        }

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

        /// <summary>
        /// 비트맵 구하기
        /// </summary>
        /// <param name="pictureBox">픽처 박스</param>
        /// <returns>비트맵</returns>
        public static Bitmap GetBitmap(PictureBox pictureBox)
        {
            Bitmap bitmap = null;

            if(pictureBox.Image != null)
            {
                bitmap = new Bitmap(pictureBox.Image);
            }

            return bitmap;
        }

        #endregion
        #region 비트맵 혼합하기 - BlendBitmap(sourceBitmap, overlayBitmap, bitmapFilterData)

        /// <summary>
        /// 비트맵 혼합하기
        /// </summary>
        /// <param name="sourceBitmap">소스 비트맵</param>
        /// <param name="overlayBitmap">오버레이 비트맵</param>
        /// <param name="bitmapFilterData">비트맵 필터 데이터</param>
        /// <returns>비트맵</returns>
        public static Bitmap BlendBitmap(Bitmap sourceBitmap, Bitmap overlayBitmap, BitmapFilterData bitmapFilterData)
        {
            BitmapData sourceBitmapData = sourceBitmap.LockBits
            (
                new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
                ImageLockMode.ReadWrite,
                PixelFormat.Format32bppArgb
            );

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

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

            BitmapData overlayBitmapData = overlayBitmap.LockBits
            (
                new Rectangle(0, 0, overlayBitmap.Width, overlayBitmap.Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb
            );

            byte[] overlayByteArray = new byte[overlayBitmapData.Stride * overlayBitmapData.Height];

            Marshal.Copy(overlayBitmapData.Scan0, overlayByteArray, 0, overlayByteArray.Length);

            float sourceBlue  = 0;
            float sourceGreen = 0;
            float sourceRed   = 0;

            float overlayBlue  = 0;
            float overlayGreen = 0;
            float overlayRed   = 0;

            for(int k = 0; k < sourceByteArray.Length && k < overlayByteArray.Length; k += 4)
            {
                sourceBlue  = (bitmapFilterData.SourceBlueEnabled  ? sourceByteArray[k    ] * bitmapFilterData.SourceBlueLevel  : 0);
                sourceGreen = (bitmapFilterData.SourceGreenEnabled ? sourceByteArray[k + 1] * bitmapFilterData.SourceGreenLevel : 0);
                sourceRed   = (bitmapFilterData.SourceRedEnabled   ? sourceByteArray[k + 2] * bitmapFilterData.SourceRedLevel   : 0);

                overlayBlue  = (bitmapFilterData.OverlayBlueEnabled  ? overlayByteArray[k    ] * bitmapFilterData.OverlayBlueLevel  : 0);
                overlayGreen = (bitmapFilterData.OverlayGreenEnabled ? overlayByteArray[k + 1] * bitmapFilterData.OverlayGreenLevel : 0);
                overlayRed   = (bitmapFilterData.OverlayRedEnabled   ? overlayByteArray[k + 2] * bitmapFilterData.OverlayRedLevel   : 0);

                sourceByteArray[k    ] = CalculateColorComponentBlendValue(sourceBlue , overlayBlue , bitmapFilterData.BlendTypeBlue );
                sourceByteArray[k + 1] = CalculateColorComponentBlendValue(sourceGreen, overlayGreen, bitmapFilterData.BlendTypeGreen);
                sourceByteArray[k + 2] = CalculateColorComponentBlendValue(sourceRed  , overlayRed  , bitmapFilterData.BlendTypeRed  );
            }

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

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

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

            targetBitmap.UnlockBits(targetBitmapData);
            sourceBitmap.UnlockBits(sourceBitmapData);
            overlayBitmap.UnlockBits(overlayBitmapData);

            return targetBitmap;
        }

        #endregion

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

        #region 색상 컴포넌트 블렌드 값 계산하기 - CalculateColorComponentBlendValue(source, overlay, blendType)

        /// <summary>
        /// 색상 컴포넌트 블렌드 값 계산하기
        /// </summary>
        /// <param name="source">소스 값</param>
        /// <param name="overlay">오버레이 값</param>
        /// <param name="blendType">색상 컴포넌트 블렌드 타입</param>
        /// <returns>색상 컴포넌트 블렌드 값</returns>
        private static byte CalculateColorComponentBlendValue(float source, float overlay, ColorComponentBlendType blendType)
        {
            float resultFloat = 0;
            byte  resultByte  = 0;

            if(blendType == ColorComponentBlendType.Add)
            {
                resultFloat = source + overlay;
            }
            else if(blendType == ColorComponentBlendType.Subtract)
            {
                resultFloat = source - overlay;
            }
            else if(blendType == ColorComponentBlendType.Average)
            {
                resultFloat = (source + overlay) / 2.0f;
            }
            else if(blendType == ColorComponentBlendType.AscendingOrder)
            {
                resultFloat = (source > overlay ? overlay : source);
            }
            else if(blendType == ColorComponentBlendType.DescendingOrder)
            {
                resultFloat = (source < overlay ? overlay : source);
            }

            if(resultFloat > 255)
            {
                resultByte = 255;
            }
            else if(resultFloat < 0)
            {
                resultByte = 0;
            }
            else
            {
                resultByte = (byte)resultFloat;
            }

            return resultByte;
        }

        #endregion
        #region 비트맵 구하기 - GetBitmap(sourceBitmap, width, height)

        /// <summary>
        /// 비트맵 구하기
        /// </summary>
        /// <param name="sourceBitmap">소스 비트맵</param>
        /// <param name="width">너비</param>
        /// <param name="height">높이</param>
        /// <returns>비트맵</returns>
        private static Bitmap GetBitmap(Bitmap sourceBitmap, int width, int height)
        {
            Bitmap targetBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);

            using(Graphics targetGraphics = Graphics.FromImage(targetBitmap))
            {
                targetGraphics.CompositingQuality = CompositingQuality.HighQuality;
                targetGraphics.InterpolationMode  = InterpolationMode.HighQualityBilinear;
                targetGraphics.PixelOffsetMode    = PixelOffsetMode.HighQuality;
                targetGraphics.SmoothingMode      = SmoothingMode.HighQuality;

                targetGraphics.DrawImage
                (
                    sourceBitmap,
                    new Rectangle(0, 0, targetBitmap.Width, targetBitmap.Height),
                    new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
                    GraphicsUnit.Pixel
                );

                targetGraphics.Flush();
            }

            return targetBitmap;
        }

        #endregion
    }
}

 

▶ MainForm.cs

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

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

        #region Field

        /// <summary>
        /// 비트맵 필터 데이터
        /// </summary>
        private BitmapFilterData filterData = new BitmapFilterData();

        /// <summary>
        /// 오버레이 이미지 경로
        /// </summary>
        private string overlayImagePath = string.Empty;

        /// <summary>
        /// 타겟 비트맵
        /// </summary>
        private Bitmap targetBitmap = null;

        /// <summary>
        /// 컨트롤 이벤트 무시 여부
        /// </summary>
        private bool ignoreControlEvent = false;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

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

            this.blendTypeBlueComboBox.Items.Add(ColorComponentBlendType.Add            );
            this.blendTypeBlueComboBox.Items.Add(ColorComponentBlendType.Average        );
            this.blendTypeBlueComboBox.Items.Add(ColorComponentBlendType.AscendingOrder );
            this.blendTypeBlueComboBox.Items.Add(ColorComponentBlendType.DescendingOrder);
            this.blendTypeBlueComboBox.Items.Add(ColorComponentBlendType.Subtract       );

            this.blendTypeBlueComboBox.SelectedIndex = 0;

            this.blendTypeGreenComboBox.Items.Add(ColorComponentBlendType.Add            );
            this.blendTypeGreenComboBox.Items.Add(ColorComponentBlendType.Average        );
            this.blendTypeGreenComboBox.Items.Add(ColorComponentBlendType.AscendingOrder );
            this.blendTypeGreenComboBox.Items.Add(ColorComponentBlendType.DescendingOrder);
            this.blendTypeGreenComboBox.Items.Add(ColorComponentBlendType.Subtract       );

            this.blendTypeGreenComboBox.SelectedIndex = 0;

            this.blendTypeRedComboBox.Items.Add(ColorComponentBlendType.Add            );
            this.blendTypeRedComboBox.Items.Add(ColorComponentBlendType.Average        );
            this.blendTypeRedComboBox.Items.Add(ColorComponentBlendType.AscendingOrder );
            this.blendTypeRedComboBox.Items.Add(ColorComponentBlendType.DescendingOrder);
            this.blendTypeRedComboBox.Items.Add(ColorComponentBlendType.Subtract       );

            this.blendTypeRedComboBox.SelectedIndex = 0;

            this.loadSourceImageButton.Click                 += loadSourceImageButton_Click;
            this.loadOverlayImageButton.Click                += loadOverlayImageButton_Click;
            this.enableSourceBlueCheckBox.CheckedChanged     += enableCheckBox_CheckedChanged;
            this.enableSourceGreenCheckBox.CheckedChanged    += enableCheckBox_CheckedChanged;
            this.enableSourceRedCheckBox.CheckedChanged      += enableCheckBox_CheckedChanged;
            this.sourceBlueLevelTrackBar.ValueChanged        += levelTrackBar_ValueChanged ;
            this.sourceGreenLevelTrackBar.ValueChanged       += levelTrackBar_ValueChanged ;
            this.sourceRedLevelTrackBar.ValueChanged         += levelTrackBar_ValueChanged ;
            this.enableOverlayBlueCheckBox.CheckedChanged    += enableCheckBox_CheckedChanged;
            this.enableOverlayGreenCheckBox.CheckedChanged   += enableCheckBox_CheckedChanged;
            this.enableOverlayRedCheckBox.CheckedChanged     += enableCheckBox_CheckedChanged;
            this.overlayBlueLevelTrackBar.ValueChanged       += levelTrackBar_ValueChanged ;
            this.overlayGreenLevelTrackBar.ValueChanged      += levelTrackBar_ValueChanged ;
            this.overlayRedLevelTrackBar.ValueChanged        += levelTrackBar_ValueChanged ;
            this.blendTypeBlueComboBox.SelectedIndexChanged  += blendTypeComboBox_SelectedIndexChanged;
            this.blendTypeGreenComboBox.SelectedIndexChanged += blendTypeComboBox_SelectedIndexChanged;
            this.blendTypeRedComboBox.SelectedIndexChanged   += blendTypeComboBox_SelectedIndexChanged;
            this.saveImageButton.Click                       += saveImageButton_Click;
            this.saveFilterButton.Click                      += saveFilterButton_Click;
            this.loadFilterButton.Click                      += loadFilterButton_Click;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

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

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

            openFileDialog.Title  = "소스 이미지 파일 선택";
            openFileDialog.Filter = "이미지 파일(*.BMP;*.JPG;*.PNG)|*.BMP;*.JPG;*.PNG|모든 파일(*.*)|*.*";

            if(openFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.sourcePictureBox.Image = BitmapHelper.GetBitmap(openFileDialog.FileName);

                CreateOverlayImage();

                RenderOverlayBitmap();
            }
        }

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

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

            openFileDialog.Title  = "오버레이 이미지 파일 선택";
            openFileDialog.Filter = "이미지 파일(*.BMP;*.JPG;*.PNG)|*.BMP;*.JPG;*.PNG|모든 파일(*.*)|*.*";

            if(openFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.overlayImagePath = openFileDialog.FileName;

                CreateOverlayImage();

                RenderOverlayBitmap();
            }
        }

        #endregion
        #region 이용 가능 체크 박스 체크 변경시 처리하기 - enableCheckBox_CheckedChanged(sender, e)

        /// <summary>
        /// 이용 가능 체크 박스 체크 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자 \</param>
        private void enableCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            RenderOverlayBitmap();
        }

        #endregion
        #region 레벨 트랙바 값 변경시 처리하기 - levelTrackBar_ValueChanged(sender, e)

        /// <summary>
        /// 레벨 트랙바 값 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자 \</param>
        private void levelTrackBar_ValueChanged(object sender, EventArgs e)
        {
            this.sourceLevelBlueLabel.Text  = "B:" + this.sourceBlueLevelTrackBar.Value  + "%";
            this.sourceLevelGreenLabel.Text = "G:" + this.sourceGreenLevelTrackBar.Value + "%";
            this.sourceLevelRedLabel.Text   = "R:" + this.sourceRedLevelTrackBar.Value   + "%";

            this.overlayLevelBlueLabel.Text  = "B:" + this.overlayBlueLevelTrackBar.Value  + "%";
            this.overlayLevelGreenLabel.Text = "G:" + this.overlayGreenLevelTrackBar.Value + "%";
            this.overlayLevelRedLabel.Text   = "R:" + this.overlayRedLevelTrackBar.Value   + "%";

            RenderOverlayBitmap();
        }

        #endregion
        #region 블렌드 타입 콤보 박스 선택 인덱스 변경시 처리하기 - blendTypeComboBox_SelectedIndexChanged(sender, e)

        /// <summary>
        /// 블렌드 타입 콤보 박스 선택 인덱스 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자 \</param>
        private void blendTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            RenderOverlayBitmap();
        }

        #endregion
        #region 이미지 저장 버튼 클릭시 처리하기 - saveImageButton_Click(sender, e)

        /// <summary>
        /// 이미지 저장 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void saveImageButton_Click(object sender, EventArgs e)
        {
            if(this.targetBitmap == null)
            {
                return;
            }
            
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Title  = "이미지 파일 선택";
            saveFileDialog.Filter = "이미지 파일(*.BMP;*.JPG;*.PNG)|*.BMP;*.JPG;*.PNG|모든 파일(*.*)|*.*";

            if(saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                string fileExtension = Path.GetExtension(saveFileDialog.FileName);

                ImageFormat imageFormat = ImageFormat.Png;

                if(fileExtension == "BMP")
                {
                    imageFormat = ImageFormat.Bmp;
                }
                else if(fileExtension == "JPG")
                {
                    imageFormat = ImageFormat.Jpeg;
                }

                StreamWriter streamWriter = new StreamWriter(saveFileDialog.FileName, false);
    
                targetPictureBox.Image.Save(streamWriter.BaseStream, imageFormat);
                
                streamWriter.Flush();
                streamWriter.Close();
            }
        }

        #endregion
        #region 필터 저장 버튼 클릭시 처리하기 - saveFilterButton_Click(sender, e)

        /// <summary>
        /// 필터 저장 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자 \</param>
        private void saveFilterButton_Click(object sender, EventArgs e)
        {
            if(this.filterData == null)
            {
                return;
            }

            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Title        = "이미지 필터 파일 선택";
            saveFileDialog.Filter       = "이미지 필터 파일(*.filter)|*.filter";
            saveFileDialog.AddExtension = true;

            if(saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                string xmlString = BitmapFilterData.Serialize(this.filterData);

                File.WriteAllText(saveFileDialog.FileName, xmlString, Encoding.UTF8);
            }
        }

        #endregion
        #region 필터 로드 버튼 클릭시 처리하기 - loadFilterButton_Click(sender, e)

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

            openFileDialog.Title  = "이미지 필터 파일 선택";
            openFileDialog.Filter = "이미지 필터 파일(*.filter)|*.filter";

            if(openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string xmlString = File.ReadAllText(openFileDialog.FileName, Encoding.UTF8);

                BitmapFilterData filterData = BitmapFilterData.Deserialize(xmlString);

                if(filterData == null)
                {
                    MessageBox.Show
                    (
                        "The selected file could not be processed!",
                        "Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Exclamation
                    );

                    return;
                }

                this.filterData = filterData;

                SetControlData();

                RenderOverlayBitmap();
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 오버레이 이미지 생성하기 - CreateOverlayImage()

        /// <summary>
        /// 오버레이 이미지 생성하기
        /// </summary>
        private void CreateOverlayImage()
        {
            if(this.overlayImagePath != string.Empty)
            {
                Size? sourceImageSize = null;

                if(this.sourcePictureBox.Image != null)
                {
                    sourceImageSize = new Size
                    (
                        this.sourcePictureBox.Image.Width,
                        this.sourcePictureBox.Image.Height
                    );
                }

                this.overlayPictureBox.Image = BitmapHelper.GetBitmap(this.overlayImagePath, sourceImageSize);
            }
        }

        #endregion
        #region 오버레이 비트맵 렌더링하기 - RenderOverlayBitmap()

        /// <summary>
        /// 오버레이 비트맵 렌더링하기
        /// </summary>
        private void RenderOverlayBitmap()
        {
            if(this.sourcePictureBox.Image == null || this.overlayPictureBox.Image == null || this.ignoreControlEvent == true)
            {
                return;
            }

            this.filterData.BlendTypeBlue  = (ColorComponentBlendType)this.blendTypeBlueComboBox.SelectedItem;
            this.filterData.BlendTypeGreen = (ColorComponentBlendType)this.blendTypeGreenComboBox.SelectedItem;
            this.filterData.BlendTypeRed   = (ColorComponentBlendType)this.blendTypeRedComboBox.SelectedItem;

            this.filterData.OverlayBlueEnabled  = this.enableOverlayBlueCheckBox.Checked;
            this.filterData.OverlayGreenEnabled = this.enableOverlayGreenCheckBox.Checked;
            this.filterData.OverlayRedEnabled   = this.enableOverlayRedCheckBox.Checked;

            this.filterData.OverlayBlueLevel  = (float)this.overlayBlueLevelTrackBar.Value  / 100.0f;
            this.filterData.OverlayGreenLevel = (float)this.overlayGreenLevelTrackBar.Value / 100.0f;
            this.filterData.OverlayRedLevel   = (float)this.overlayRedLevelTrackBar.Value   / 100.0f;

            this.filterData.SourceBlueEnabled  = this.enableSourceBlueCheckBox.Checked;
            this.filterData.SourceGreenEnabled = this.enableSourceGreenCheckBox.Checked;
            this.filterData.SourceRedEnabled   = this.enableSourceRedCheckBox.Checked;

            this.filterData.SourceBlueLevel  = (float)this.sourceBlueLevelTrackBar.Value  / 100.0f;
            this.filterData.SourceGreenLevel = (float)this.sourceGreenLevelTrackBar.Value / 100.0f;
            this.filterData.SourceRedLevel   = (float)this.sourceRedLevelTrackBar.Value   / 100.0f;

            using(Bitmap sourceBitmap = BitmapHelper.GetBitmap(this.sourcePictureBox))
            {
                using(Bitmap overlayBitmap = BitmapHelper.GetBitmap(this.overlayPictureBox))
                {
                    this.targetBitmap = BitmapHelper.BlendBitmap(sourceBitmap, overlayBitmap, filterData);

                    this.targetPictureBox.Image = targetBitmap;
                }
            }
        }

        #endregion
        #region 컨트롤 데이터 설정하기 - SetControlData()

        /// <summary>
        /// 컨트롤 데이터 설정하기
        /// </summary>
        private void SetControlData()
        {
            this.ignoreControlEvent = true;

            this.enableSourceBlueCheckBox.Checked  = this.filterData.SourceBlueEnabled;
            this.enableSourceGreenCheckBox.Checked = this.filterData.SourceGreenEnabled;
            this.enableSourceRedCheckBox.Checked   = this.filterData.SourceRedEnabled;

            this.sourceBlueLevelTrackBar.Value  = (int)(this.filterData.SourceBlueLevel  * 100);
            this.sourceGreenLevelTrackBar.Value = (int)(this.filterData.SourceGreenLevel * 100);
            this.sourceRedLevelTrackBar.Value   = (int)(this.filterData.SourceRedLevel   * 100);

            this.enableOverlayBlueCheckBox.Checked  = this.filterData.OverlayBlueEnabled;
            this.enableOverlayGreenCheckBox.Checked = this.filterData.OverlayGreenEnabled;
            this.enableOverlayRedCheckBox.Checked   = this.filterData.OverlayRedEnabled;

            this.overlayBlueLevelTrackBar.Value  = (int)(this.filterData.OverlayBlueLevel  * 100);
            this.overlayGreenLevelTrackBar.Value = (int)(this.filterData.OverlayGreenLevel * 100);
            this.overlayRedLevelTrackBar.Value   = (int)(this.filterData.OverlayRedLevel   * 100);

            this.blendTypeBlueComboBox.SelectedItem  = this.filterData.BlendTypeBlue;
            this.blendTypeGreenComboBox.SelectedItem = this.filterData.BlendTypeGreen;
            this.blendTypeRedComboBox.SelectedItem   = this.filterData.BlendTypeRed;

            this.ignoreControlEvent = false;
        }

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

댓글을 달아 주세요