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

TestProject.zip
다운로드

▶ ImageExtension.cs

using System.Drawing;
using System.Drawing.Imaging;

namespace TestProject
{
    /// <summary>
    /// 이미지 확장
    /// </summary>
    public static class ImageExtension
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 이미지 복사하기 -  CopyImage(sourceImage)

        /// <summary>
        /// 이미지 복사하기
        /// </summary>
        /// <param name="sourceImage">소스 이미지</param>
        /// <returns>이미지</returns>
        public static Image CopyImage(this Image sourceImage)
        {
            return (Image)sourceImage.Clone();
        }

        #endregion
        #region 이미지 복사하기 - CopyImage(sourceImage, imageAttributes)

        /// <summary>
        /// 이미지 복사하기
        /// </summary>
        /// <param name="sourceImage">소스 이미지</param>
        /// <param name="imageAttributes">이미지 어트리뷰트</param>
        /// <returns>이미지</returns>
        public static Image CopyImage(this Image sourceImage, ImageAttributes imageAttributes)
        {
            Bitmap targetBitmap = new Bitmap(sourceImage.Width, sourceImage.Height);

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

                graphics.DrawImage
                (
                    sourceImage,
                    targetRectangle,
                    0,
                    0,
                    sourceImage.Width,
                    sourceImage.Height,
                    GraphicsUnit.Pixel,
                    imageAttributes
                );
            }

            return targetBitmap;
        }

        #endregion
    }
}

 

728x90

 

▶ MainForm.cs

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

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

        #region Field

        /// <summary>
        /// 텍스트 박스 배열 배열
        /// </summary>
        private TextBox[][] textBoxArrayArray;

        #endregion

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

        #region 생성자 - MainForm()

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

            this.Load                     += Form_Load;
            this.openMenuItem.Click       += openMenuItem_Click;
            this.saveAsMenuItem.Click     += saveAsMenuItem_Click;
            this.exitMenuItem.Click       += exitMenuItem_Click;
            this.identityMenuItem.Click   += presetMenuItem_Click;
            this.redMenuItem.Click        += presetMenuItem_Click;
            this.limeMenuItem.Click       += presetMenuItem_Click;
            this.blueMenuItem.Click       += presetMenuItem_Click;
            this.greenMenuItem.Click      += presetMenuItem_Click;
            this.yellowMenuItem.Click     += presetMenuItem_Click;
            this.orangeMenuItem.Click     += presetMenuItem_Click;
            this.pinkMenuItem.Click       += presetMenuItem_Click;
            this.lightGreenMenuItem.Click += presetMenuItem_Click;
            this.lightBlueMenuItem.Click  += presetMenuItem_Click;
            this.cyanMenuItem.Click       += presetMenuItem_Click;
            this.fuchsiaMenuItem.Click    += presetMenuItem_Click;
            this.averageMenuItem.Click    += presetMenuItem_Click;
            this.monochromeMenuItem.Click += presetMenuItem_Click;
            this.sepiaMenuItem.Click      += presetMenuItem_Click;
            this.brighterButton.Click     += brighterButton_Click;
            this.darkerButton.Click       += darkerButton_Click;
            this.colorizeButton.Click     += colorizeButton_Click;
        }

        #endregion

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

        #region 폼 로드시 처리하기 - Form_Load(sender, e)

        /// <summary>
        /// 폼 로드시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Form_Load(object sender, EventArgs e)
        {
            this.textBoxArrayArray = new TextBox[][]
            {
                new TextBox[] { this.value00TextBox, this.value01TextBox, this.value02TextBox, this.value03TextBox, this.value04TextBox },
                new TextBox[] { this.value10TextBox, this.value11TextBox, this.value12TextBox, this.value13TextBox, this.value14TextBox },
                new TextBox[] { this.value20TextBox, this.value21TextBox, this.value22TextBox, this.value23TextBox, this.value24TextBox },
                new TextBox[] { this.value30TextBox, this.value31TextBox, this.value32TextBox, this.value33TextBox, this.value34TextBox },
                new TextBox[] { this.value40TextBox, this.value41TextBox, this.value42TextBox, this.value43TextBox, this.value44TextBox }
            };
        }

        #endregion
        #region 열기 메뉴 항목 클릭시 처리하기 - openMenuItem_Click(sender, e)

        /// <summary>
        /// 열기 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void openMenuItem_Click(object sender, EventArgs e)
        {
            if(this.openFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.sourcePictureBox.Image = GetBitmap(this.openFileDialog.FileName);

                Colorize();
            }
        }

        #endregion
        #region 다른 이름으로 저장 메뉴 항목 클릭시 처리하기 - saveAsMenuItem_Click(sender, e)

        /// <summary>
        /// 다른 이름으로 저장 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void saveAsMenuItem_Click(object sender, EventArgs e)
        {
            if(this.saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                SaveImage(this.targetPictureBox.Image, this.saveFileDialog.FileName);
            }
        }

        #endregion
        #region 종료 메뉴 항목 클릭시 처리하기 - exitMenuItem_Click(sender, e)

        /// <summary>
        /// 종료 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void exitMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        #endregion
        #region 기정의 세트 메뉴 항목 클릭시 처리하기 - presetMenuItem_Click(sender, e)

        /// <summary>
        /// 기정의 세트 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void presetMenuItem_Click(object sender, EventArgs e)
        {
            foreach(TextBox[] textBoxArray in this.textBoxArrayArray)
            {
                foreach(TextBox textBox in textBoxArray)
                {
                    textBox.Text = "0.0000";
                }
            }

            for(int i = 3; i < 5; i++)
            {
                this.textBoxArrayArray[i][i].Text = "1.0000";
            }

            ToolStripMenuItem menuItem = sender as ToolStripMenuItem;

            if(menuItem.Tag.ToString().ToLower() == "배경색 사용")
            {
                Color color = menuItem.BackColor;

                this.value00TextBox.Text = (color.R / 255f).ToString("f4");
                this.value11TextBox.Text = (color.G / 255f).ToString("f4");
                this.value22TextBox.Text = (color.B / 255f).ToString("f4");
                this.value33TextBox.Text = "1.0000";
                this.value44TextBox.Text = "1.0000";
            }
            else
            {
                string colorName = menuItem.Text.Replace("&", "").ToLower();

                if(colorName == "identity")
                {
                    for(int i = 0; i < 3; i++)
                    {
                        this.textBoxArrayArray[i][i].Text = "1.0000";
                    }
                }
                else if(colorName == "average")
                {
                    for(int i = 0; i < 3; i++)
                    {
                        for(int j = 0; j < 3; j++)
                        {
                            this.textBoxArrayArray[i][j].Text = "0.3333";
                        }
                    }
                }
                else if(colorName == "monochrome")
                {
                    for(int i = 0; i < 3; i++)
                    {
                        this.textBoxArrayArray[0][i].Text = "0.2990";
                    }

                    for(int i = 0; i < 3; i++)
                    {
                        this.textBoxArrayArray[1][i].Text = "0.5870";
                    }

                    for(int i = 0; i < 3; i++)
                    {
                        this.textBoxArrayArray[2][i].Text = "0.1140";
                    }
                }
                else if(colorName == "sepia")
                {
                    this.value00TextBox.Text = "0.3930";
                    this.value01TextBox.Text = "0.3490";
                    this.value02TextBox.Text = "0.2720";
                    this.value10TextBox.Text = "0.7690";
                    this.value11TextBox.Text = "0.6860";
                    this.value12TextBox.Text = "0.5340";
                    this.value20TextBox.Text = "0.1890";
                    this.value20TextBox.Text = "0.1680";
                    this.value20TextBox.Text = "0.1310";
                }
                else
                {
                    MessageBox.Show("Unknown preset");

                    return;
                }
            }

            Colorize();
        }

        #endregion
        #region 밝게 버튼 클릭시 처리하기 - brighterButton_Click(sender, e)

        /// <summary>
        /// 밝게 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void brighterButton_Click(object sender, EventArgs e)
        {
            float[][] valueArray = GetMatrix();

            for(int i = 0; i < 3; i++)
            {
                for(int j = 0; j < 3; j++)
                {
                    if(Math.Abs(valueArray[i][j]) < 0.01f)
                    {
                        continue;
                    }

                    valueArray[i][j] += 0.1f;
                }
            }

            SaveMatrix(valueArray);

            Colorize();
        }

        #endregion
        #region 어둡게 버튼 클릭시 처리하기 - darkerButton_Click(sender, e)

        /// <summary>
        /// 어둡게 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void darkerButton_Click(object sender, EventArgs e)
        {
            float[][] valueArrayArray = GetMatrix();

            for(int i = 0; i < 3; i++)
            {
                for(int j = 0; j < 3; j++)
                {
                    if(Math.Abs(valueArrayArray[i][j]) < 0.01f)
                    {
                        continue;
                    }

                    valueArrayArray[i][j] -= 0.1f;

                    if(valueArrayArray[i][j] < 0f)
                    {
                        valueArrayArray[i][j] = 0f;
                    }
                }
            }

            SaveMatrix(valueArrayArray);

            Colorize();
        }

        #endregion
        #region 채색하기 버튼 클릭시 처리하기 - colorizeButton_Click(sender, e)

        /// <summary>
        /// 채색하기 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void colorizeButton_Click(object sender, EventArgs e)
        {
            Colorize();
        }

        #endregion

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

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

        /// <summary>
        /// 비트맵 구하기
        /// </summary>
        /// <param name="filePath">파일 경로</param>
        /// <returns>비트맵</returns>
        private Bitmap GetBitmap(string filePath)
        {
            using(Bitmap bitmap = new Bitmap(filePath))
            {
                return new Bitmap(bitmap);
            }
        }

        #endregion
        #region 매트릭스 구하기 - GetMatrix()

        /// <summary>
        /// 매트릭스 구하기
        /// </summary>
        /// <returns>매트릭스</returns>
        private float[][] GetMatrix()
        {
            float[][] valueArray = new float[][]
            {
                new float[5],
                new float[5],
                new float[5],
                new float[5],
                new float[5],
            };

            for(int i = 0; i < 5; i++)
            {
                for(int j = 0; j < 5; j++)
                {
                    float value;

                    if(!float.TryParse(this.textBoxArrayArray[i][j].Text, out value))
                    {
                        MessageBox.Show("Invalid entry");

                        this.textBoxArrayArray[i][j].Focus();

                        return null;
                    }

                    valueArray[i][j] = value;
                }
            }

            return valueArray;
        }

        #endregion
        #region 색상 매트릭스 구하기 - GetColorMatrix()

        /// <summary>
        /// 색상 매트릭스 구하기
        /// </summary>
        /// <returns>색상 매트릭스</returns>
        private ColorMatrix GetColorMatrix()
        {
            float[][] valueArray = GetMatrix();

            if(valueArray == null)
            {
                return null;
            }

            return new ColorMatrix(valueArray);
        }

        #endregion
        #region 이미지 구하기 - GetImage(image, colorMatrix)

        /// <summary>
        /// 이미지 구하기
        /// </summary>
        /// <param name="image">이미지</param>
        /// <param name="colorMatrix">색상 매트릭스</param>
        /// <returns>이미지</returns>
        private Image GetImage(Image image, ColorMatrix colorMatrix)
        {
            ImageAttributes imageAttributes = new ImageAttributes();

            imageAttributes.SetColorMatrix(colorMatrix);

            return image.CopyImage(imageAttributes);
        }

        #endregion
        #region 채색하기 - Colorize()

        /// <summary>
        /// 채색하기
        /// </summary>
        private void Colorize()
        {
            ColorMatrix colorMatrix = GetColorMatrix();

            this.targetPictureBox.Image = GetImage(this.sourcePictureBox.Image, colorMatrix);

            this.saveAsMenuItem.Enabled = (this.targetPictureBox.Image != null);
        }

        #endregion
        #region 이미지 저장하기 - SaveImage(image, filePath)

        /// <summary>
        /// 이미지 저장하기
        /// </summary>
        /// <param name="image">이미지</param>
        /// <param name="filePath">파일 경로</param>
        private void SaveImage(Image image, string filePath)
        {
            string fileExtension = Path.GetExtension(filePath);

            switch(fileExtension.ToLower())
            {
                case ".bmp"  : image.Save(filePath, ImageFormat.Bmp ); break;
                case ".exif" : image.Save(filePath, ImageFormat.Exif); break;
                case ".gif"  : image.Save(filePath, ImageFormat.Gif ); break;
                case ".jpg"  :
                case ".jpeg" : image.Save(filePath, ImageFormat.Jpeg); break;
                case ".png"  : image.Save(filePath, ImageFormat.Png ); break;
                case ".tif"  :
                case ".tiff" : image.Save(filePath, ImageFormat.Tiff); break;
                default      : throw new NotSupportedException("Unknown file extension " + fileExtension);
            }
        }

        #endregion
        #region 매트릭스 저장하기 - SaveMatrix(valueArrayArray)

        /// <summary>
        /// 매트릭스 저장하기
        /// </summary>
        /// <param name="valueArrayArray">값 배열 배열</param>
        private void SaveMatrix(float[][] valueArrayArray)
        {
            for(int i = 0; i < 5; i++)
            {
                for(int j = 0; j < 5; j++)
                {
                    this.textBoxArrayArray[i][j].Text = valueArrayArray[i][j].ToString("f4");
                }
            }
        }

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

댓글을 달아 주세요