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

TestProject.zip
다운로드

▶ MainForm.cs

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

using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.ViewInfo;

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

        #region Field

        /// <summary>
        /// 소스 이미지 디렉토리 경로
        /// </summary>
        private string sourceImageDirectoryPath = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;

        /// <summary>
        /// 소스 이미지
        /// </summary>
        private Image sourceImage;

        /// <summary>
        /// 마우스 DOWN 포인트
        /// </summary>
        private Point mouseDownPoint = Point.Empty;

        /// <summary>
        /// 올가미 밧줄 사각형
        /// </summary>
        private Rectangle lassoRectangle = Rectangle.Empty;

        /// <summary>
        /// 확대/축소 퍼센트 변경 여부
        /// </summary>
        private bool zoomPercentChanged;

        /// <summary>
        /// 올가미 밧줄 펜
        /// </summary>
        private Pen lassoPen = new Pen(Color.Red);

        #endregion

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

        #region 생성자 - MainForm()

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

            #region 소스 이미지를 설정한다.

            this.sourceImage = Image.FromFile(this.sourceImageDirectoryPath + @"\sample.jpg");

            #endregion
            #region 소스 픽처 에디터를 설정한다.

            this.sourcePictureEdit.Properties.ShowZoomSubMenu         = DevExpress.Utils.DefaultBoolean.True;
            this.sourcePictureEdit.Properties.ShowScrollBars          = true;
            this.sourcePictureEdit.Properties.AllowScrollViaMouseDrag = false;
            this.sourcePictureEdit.EditValue                          = sourceImage;

            #endregion
            #region 그림 크기 모드 콤보 에디터를 설정한다.

            this.pictureSizeModeComboBoxEdit.Properties.Items.AddRange
            (
                new PictureSizeMode[]
                {
                    PictureSizeMode.Clip,
                    PictureSizeMode.Squeeze,
                    PictureSizeMode.Stretch,
                    PictureSizeMode.StretchHorizontal,
                    PictureSizeMode.StretchVertical,
                    PictureSizeMode.Zoom
                }
            );

            this.pictureSizeModeComboBoxEdit.SelectedIndex = 0;

            #endregion
            #region 이벤트를 설정한다.

            this.pictureSizeModeComboBoxEdit.EditValueChanged += pictureSizeModeComboBoxEdit_EditValueChanged;

            this.sourcePictureEdit.HScrollBar.ValueChanged += sourcePictureEdit_ScrollBar_ValueChanged;
            this.sourcePictureEdit.VScrollBar.ValueChanged += sourcePictureEdit_ScrollBar_ValueChanged;
            this.sourcePictureEdit.MouseDown               += sourcePictureEdit_MouseDown;
            this.sourcePictureEdit.MouseMove               += sourcePictureEdit_MouseMove;
            this.sourcePictureEdit.MouseUp                 += sourcePictureEdit_MouseUp;
            this.sourcePictureEdit.ZoomPercentChanged      += sourcePictureEdit_ZoomPercentChanged;
            this.sourcePictureEdit.Paint                   += sourcePictureEdit_Paint;

            #endregion
        }

        #endregion

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

        #region 그림 크기 모드 콤보 에디터 편집 값 변경시 처리하기 - pictureSizeModeComboBoxEdit_EditValueChanged(sender, e)

        /// <summary>
        /// 그림 크기 모드 콤보 에디터 편집 값 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void pictureSizeModeComboBoxEdit_EditValueChanged(object sender, EventArgs e)
        {
            ComboBoxEdit comboBoxEdit = sender as ComboBoxEdit;

            this.sourcePictureEdit.Properties.SizeMode = (PictureSizeMode)comboBoxEdit.EditValue;

            this.zoomPercentChanged = false;
        }

        #endregion

        #region 소스 픽처 에디터 스크롤바 값 변경시 처리하기 - sourcePictureEdit_ScrollBar_ValueChanged(sender, e)

        /// <summary>
        /// 소스 픽처 에디터 스크롤바 값 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void sourcePictureEdit_ScrollBar_ValueChanged(object sender, EventArgs e)
        {
            ResetLassoRectangle();
        }

        #endregion
        #region 소스 픽처 에디터 확대/축소 퍼센트 변경시 처리하기 - sourcePictureEdit_ZoomPercentChanged(sender, e)

        /// <summary>
        /// 소스 픽처 에디터 확대/축소 퍼센트 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void sourcePictureEdit_ZoomPercentChanged(object sender, EventArgs e)
        {
            this.zoomPercentChanged = true;

            ResetLassoRectangle();
        }

        #endregion
        #region 소스 픽처 에디터 마우스 DOWN 처리하기 - sourcePictureEdit_MouseDown(sender, e)

        /// <summary>
        /// 소스 픽처 에디터 마우스 DOWN 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void sourcePictureEdit_MouseDown(object sender, MouseEventArgs e)
        {
            if(e.Button != MouseButtons.Left)
            {
                return;
            }

            this.mouseDownPoint = e.Location;

            ResetLassoRectangle();

            PictureEdit pictureEdit = sender as PictureEdit;

            pictureEdit.Refresh();
        }

        #endregion
        #region 소스 픽처 에디터 마우스 이동시 처리하기 - sourcePictureEdit_MouseMove(object sender, MouseEventArgs e)

        /// <summary>
        /// 소스 픽처 에디터 마우스 이동시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void sourcePictureEdit_MouseMove(object sender, MouseEventArgs e)
        {
            if(this.mouseDownPoint.IsEmpty)
            {
                return;
            }

            if(e.Button != MouseButtons.Left)
            {
                return;
            }

            Point mouseMovePoint = e.Location;

            if(CheckBoundRectangle(mouseMovePoint.X, mouseMovePoint.Y))
            {
                this.lassoRectangle = new Rectangle
                (
                    mouseDownPoint.X,
                    mouseDownPoint.Y,
                    mouseMovePoint.X - mouseDownPoint.X,
                    mouseMovePoint.Y - mouseDownPoint.Y
                );

                PictureEdit pictureEdit = sender as PictureEdit;

                pictureEdit.Refresh();
            }
        }

        #endregion
        #region 소스 픽처 에디터 마우스 UP 처리하기 - sourcePictureEdit_MouseUp(sender, e)

        /// <summary>
        /// 소스 픽처 에디터 마우스 UP 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void sourcePictureEdit_MouseUp(object sender, MouseEventArgs e)
        {
            PictureEdit pictureEdit = sender as PictureEdit;

            Point startPoint = ConvertPoint(pictureEdit, lassoRectangle.Location);
            Point endPoint   = ConvertPoint(pictureEdit , new Point(lassoRectangle.Right, lassoRectangle.Bottom));

            Rectangle selectedImageRectangle = new Rectangle
            (
                startPoint.X,
                startPoint.Y,
                endPoint.X - startPoint.X,
                endPoint.Y - startPoint.Y
            );

            if(selectedImageRectangle.Size.Width <= 0 || selectedImageRectangle.Size.Height <= 0)
            {
                return;
            }

            Bitmap selectedImage = new Bitmap(sourceImage);

            this.targetPictureEdit.EditValue = selectedImage.Clone(selectedImageRectangle, selectedImage.PixelFormat);
        }

        #endregion
        #region 소스 픽처 에디터 페인트시 처리하기 - sourcePictureEdit_Paint(sender, e)

        /// <summary>
        /// 소스 픽처 에디터 페인트시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void sourcePictureEdit_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawRectangle(this.lassoPen, this.lassoRectangle);
        }

        #endregion

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

        #region 올가미 밧줄 사각형 리셋하기 - ResetLassoRectangle()

        /// <summary>
        /// 올가미 밧줄 사각형 리셋하기
        /// </summary>
        private void ResetLassoRectangle()
        {
            this.lassoRectangle = Rectangle.Empty;
        }

        #endregion
        #region 테두리 사각형 체크하기 - CheckBoundRectangle(x, y)

        /// <summary>
        /// 테두리 사각형 체크하기
        /// </summary>
        /// <param name="x">X 좌표</param>
        /// <param name="y">Y 좌표</param>
        /// <returns>체크 결과</returns>
        private bool CheckBoundRectangle(int x, int y)
        {
            return x >= 0 && x < this.sourcePictureEdit.Image.Width && y >= 0 && y < this.sourcePictureEdit.Image.Height;
        }

        #endregion
        #region 포인트 변환하기 - ConvertPoint(pictureEdit, sourcePoint)

        /// <summary>
        /// 포인트 변환하기
        /// </summary>
        /// <param name="pictureEdit">픽처 에디터</param>
        /// <param name="sourcePoint">소스 포인트</param>
        /// <returns>변환 포인트</returns>
        private Point ConvertPoint(PictureEdit pictureEdit, Point sourcePoint)
        {
            Point targetPoint = Point.Empty;

            if(pictureEdit.Image != null)
            {
                PictureEditViewInfo viewInfo = pictureEdit.GetViewInfo() as PictureEditViewInfo;

                double zoomX = 1.0;
                double zoomY = 1.0;

                if(this.zoomPercentChanged && pictureEdit.Properties.SizeMode != PictureSizeMode.Squeeze)
                {
                    zoomX = zoomY = Convert.ToDouble(pictureEdit.Properties.ZoomPercent) / 100;
                }
                else
                {
                    switch(pictureEdit.Properties.SizeMode)
                    {
                        case PictureSizeMode.Zoom    :
                        case PictureSizeMode.Squeeze :

                            zoomX = zoomY = Convert.ToDouble(viewInfo.PictureScreenBounds.Width / pictureEdit.Image.Size.Width);

                            break;

                        case PictureSizeMode.Stretch :

                            zoomX = Convert.ToDouble(viewInfo.PictureScreenBounds.Width  / pictureEdit.Image.Size.Width );
                            zoomY = Convert.ToDouble(viewInfo.PictureScreenBounds.Height / pictureEdit.Image.Size.Height);

                            break;

                        case PictureSizeMode.StretchHorizontal :

                            zoomX = Convert.ToDouble(viewInfo.PictureScreenBounds.Width / pictureEdit.Image.Size.Width);

                            break;

                        case PictureSizeMode.StretchVertical :

                            zoomY = zoomY = Convert.ToDouble(viewInfo.PictureScreenBounds.Height / pictureEdit.Image.Size.Height);

                            break;
                    }
                }

                int scrollX = (pictureEdit.Controls[1] as DevExpress.XtraEditors.HScrollBar).Value;
                int scrollY = (pictureEdit.Controls[0] as DevExpress.XtraEditors.VScrollBar).Value;

                int x, y;

                if(pictureEdit.Controls[1].Visible == true)
                {
                    x = (int)((sourcePoint.X + scrollX - viewInfo.PictureScreenBounds.X) / zoomX);
                }
                else
                {
                    x = (int)((sourcePoint.X - viewInfo.PictureScreenBounds.X) / zoomX);
                }

                if(pictureEdit.Controls[0].Visible == true)
                {
                    y = (int)((sourcePoint.Y + scrollY - viewInfo.PictureScreenBounds.Y) / zoomY);
                }
                else
                {
                    y = (int)((sourcePoint.Y - viewInfo.PictureScreenBounds.Y) / zoomY);
                }

                targetPoint = new Point(x, y);
            }

            return targetPoint;
        }

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

댓글을 달아 주세요