728x90
반응형
728x170
▶ MainForm.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 오버레이 비트맵
/// </summary>
private Bitmap overlayBitmap = null;
/// <summary>
/// 오버레이 스케일 비트맵
/// </summary>
private Bitmap overlayScaledBitmap = null;
/// <summary>
/// 메인 비트맵
/// </summary>
private Bitmap mainBitmap = null;
/// <summary>
/// 메인 작업 비트맵
/// </summary>
private Bitmap mainWorkingBitmap = null;
/// <summary>
/// 메인 작업 스케일 비트맵
/// </summary>
private Bitmap mainWorkingScaledBitmap = null;
/// <summary>
/// 비트맵 스케일
/// </summary>
private float bitmapScale = 1;
/// <summary>
/// 그리기 여부
/// </summary>
private bool isDrawing = false;
/// <summary>
/// 선택 영역 포인트 리스트
/// </summary>
private List<PointF> selectedAreaPointList = new List<PointF>();
/// <summary>
/// 선택 영역 스케일 포인트 리스트
/// </summary>
private List<PointF> selectedAreaScaledPointList = new List<PointF>();
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
this.openOverlayImageMenuItem.Click += openOverlayImageMenuItem_Click;
this.openMainImageMenuItem.Click += openMainImageMenuItem_Click;
this.resetMenuItem.Click += resetMenuItem_Click;
this.saveAsMenuItem.Click += saveAsMenuItem_Click;
this.exitMenuItem.Click += exitMenuItem_Click;
this.scale100MenuItem.Click += scaleMenuItem_Click;
this.scale75MenuItem.Click += scaleMenuItem_Click;
this.scale66MenuItem.Click += scaleMenuItem_Click;
this.scale50MenuItem.Click += scaleMenuItem_Click;
this.scale25MenuItem.Click += scaleMenuItem_Click;
this.scale15MenuItem.Click += scaleMenuItem_Click;
this.scale5MenuItem.Click += scaleMenuItem_Click;
this.overlayImagePictureBox.MouseDown += overlayImagePictureBox_MouseDown;
this.overlayImagePictureBox.MouseMove += overlayImagePictureBox_MouseMove;
this.overlayImagePictureBox.MouseUp += overlayImagePictureBox_MouseUp;
this.overlayImagePictureBox.Paint += overlayImagePictureBox_Paint;
this.copyButton.Click += copyButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 오버레이 이미지 열기 메뉴 항목 클릭시 처리하기 - openOverlayImageMenuItem_Click(sender, e)
/// <summary>
/// 오버레이 이미지 열기 메뉴 항목 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void openOverlayImageMenuItem_Click(object sender, EventArgs e)
{
if(this.openFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
this.overlayBitmap = LoadBitmapFile(this.openFileDialog.FileName);
this.resetMenuItem.Enabled = false;
ShowScaledBitmap();
}
catch(Exception exception)
{
MessageBox.Show(exception.Message);
}
}
}
#endregion
#region 메인 이미지 열기 메뉴 항목 클릭시 처리하기 - openMainImageMenuItem_Click(sender, e)
/// <summary>
/// 메인 이미지 열기 메뉴 항목 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void openMainImageMenuItem_Click(object sender, EventArgs e)
{
if(this.openFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
this.mainBitmap = LoadBitmapFile(this.openFileDialog.FileName);
this.mainWorkingBitmap = new Bitmap(this.mainBitmap);
this.resetMenuItem.Enabled = false;
ShowScaledBitmap();
}
catch(Exception exception)
{
MessageBox.Show(exception.Message);
}
}
}
#endregion
#region 리셋하기 메뉴 항목 클릭시 처리하기 - resetMenuItem_Click(sender, e)
/// <summary>
/// 리셋하기 메뉴 항목 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void resetMenuItem_Click(object sender, EventArgs e)
{
this.mainWorkingBitmap = new Bitmap(this.mainBitmap);
this.resetMenuItem.Enabled = false;
ShowScaledBitmap();
}
#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.mainWorkingBitmap, 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 확대/축소 메뉴 항목 클릭시 처리하기 - scaleMenuItem_Click(sender, e)
/// <summary>
/// 확대/축소 메뉴 항목 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void scaleMenuItem_Click(object sender, EventArgs e)
{
ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
string scaleText = menuItem.Text.Replace("&", "").Replace("%", "");
this.bitmapScale = float.Parse(scaleText) / 100f;
ShowScaledBitmap();
this.scaleMenuItem.Text = "확대/축소(&S) (" + menuItem.Text.Replace("&", "") + ")";
foreach(ToolStripMenuItem childMenuItem in scaleMenuItem.DropDownItems)
{
childMenuItem.Checked = (childMenuItem == menuItem);
}
ScaleSelectionArea();
}
#endregion
#region 오버레이 이미지 픽처 박스 마우스 DOWN 처리하기 - overlayImagePictureBox_MouseDown(sender, e)
/// <summary>
/// 오버레이 이미지 픽처 박스 마우스 DOWN 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void overlayImagePictureBox_MouseDown(object sender, MouseEventArgs e)
{
if(this.overlayImagePictureBox.Image == null)
{
return;
}
this.isDrawing = true;
this.selectedAreaScaledPointList = new List<PointF>();
this.selectedAreaScaledPointList.Add(e.Location);
this.selectedAreaPointList = new List<PointF>();
this.selectedAreaPointList.Add(new PointF(e.X / this.bitmapScale, e.Y / this.bitmapScale));
this.overlayImagePictureBox.Refresh();
}
#endregion
#region 오버레이 이미지 픽처 박스 마우스 이동시 처리하기 - overlayImagePictureBox_MouseMove(sender, e)
/// <summary>
/// 오버레이 이미지 픽처 박스 마우스 이동시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void overlayImagePictureBox_MouseMove(object sender, MouseEventArgs e)
{
if(!this.isDrawing)
{
return;
}
this.selectedAreaScaledPointList.Add(e.Location);
this.selectedAreaPointList.Add
(
new PointF
(
e.X / this.bitmapScale,
e.Y / this.bitmapScale
)
);
this.overlayImagePictureBox.Refresh();
}
#endregion
#region 오버레이 이미지 픽처 박스 마우스 UP 처리하기 - overlayImagePictureBox_MouseUp(sender, e)
/// <summary>
/// 오버레이 이미지 픽처 박스 마우스 UP 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void overlayImagePictureBox_MouseUp(object sender, MouseEventArgs e)
{
this.isDrawing = false;
this.overlayImagePictureBox.Refresh();
this.copyButton.Enabled = (this.selectedAreaPointList.Count > 2);
}
#endregion
#region 오버레이 이미지 픽처 박스 페인트시 처리하기 - overlayImagePictureBox_Paint(sender, e)
/// <summary>
/// 오버레이 이미지 픽처 박스 페인트시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void overlayImagePictureBox_Paint(object sender, PaintEventArgs e)
{
if(this.selectedAreaPointList.Count < 3)
{
return;
}
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
PointF[] pointArray = this.selectedAreaScaledPointList.ToArray();
using(Pen pen = new Pen(Color.Red, 2))
{
if(this.isDrawing)
{
e.Graphics.DrawLines(pen, pointArray);
}
else
{
e.Graphics.DrawPolygon(pen, pointArray);
}
pen.Color = Color.Yellow;
pen.DashPattern = new float[] { 5, 5 };
if(this.isDrawing)
{
e.Graphics.DrawLines(pen, pointArray);
}
else
{
e.Graphics.DrawPolygon(pen, pointArray);
}
}
}
#endregion
#region 복사 버튼 클릭시 처리하기 - copyButton_Click(sender, e)
/// <summary>
/// 복사 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void copyButton_Click(object sender, EventArgs e)
{
if(this.selectedAreaPointList.Count < 3)
{
return;
}
this.copyButton.Enabled = false;
this.resetMenuItem.Enabled = true;
using(Graphics graphics = Graphics.FromImage(this.mainWorkingBitmap))
{
using(TextureBrush brush = new TextureBrush(this.overlayBitmap))
{
graphics.FillPolygon(brush, this.selectedAreaPointList.ToArray());
}
}
ShowScaledBitmap();
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 비트맵 파일 로드하기 - LoadBitmapFile(filePath)
/// <summary>
/// 비트맵 파일 로드하기
/// </summary>
/// <param name="filePath">파일 경로</param>
/// <returns>비트맵</returns>
private Bitmap LoadBitmapFile(string filePath)
{
using(Bitmap bitmap = new Bitmap(filePath))
{
return new Bitmap(bitmap);
}
}
#endregion
#region 크기 변경 비트맵 구하기 - GetScaledBitmap(sourceBitmap, scale)
/// <summary>
/// 크기 변경 비트맵 구하기
/// </summary>
/// <param name="sourceBitmap">소스 비트맵</param>
/// <param name="scale">척도</param>
/// <returns>크기 조정 비트맵</returns>
private Bitmap GetScaledBitmap(Bitmap sourceBitmap, float scale)
{
int scaledWidth = (int)(sourceBitmap.Width * scale);
int scaledHeight = (int)(sourceBitmap.Height * scale);
Bitmap targetBitmap = new Bitmap(scaledWidth, scaledHeight);
using(Graphics graphics = Graphics.FromImage(targetBitmap))
{
Rectangle targetRectangle = new Rectangle(0, 0, scaledWidth , scaledHeight );
Rectangle sourceRectangle = new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height);
graphics.DrawImage(sourceBitmap, targetRectangle, sourceRectangle, GraphicsUnit.Pixel);
}
return targetBitmap;
}
#endregion
#region 크기 변경 비트맵 표시하기 - ShowScaledBitmap()
/// <summary>
/// 크기 변경 비트맵 표시하기
/// </summary>
private void ShowScaledBitmap()
{
if(this.overlayBitmap != null)
{
this.overlayScaledBitmap = GetScaledBitmap(this.overlayBitmap, this.bitmapScale);
this.overlayImagePictureBox.Image = this.overlayScaledBitmap;
this.overlayImagePictureBox.Visible = true;
}
if(this.mainWorkingBitmap != null)
{
this.mainWorkingScaledBitmap = GetScaledBitmap(this.mainWorkingBitmap, this.bitmapScale);
this.mainImagePictureBox.Image = this.mainWorkingScaledBitmap;
this.mainImagePictureBox.Visible = true;
}
this.saveAsMenuItem.Enabled = ((this.overlayBitmap != null) && (this.mainWorkingBitmap != 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 선택 영역 크기 변경하기 - ScaleSelectionArea()
/// <summary>
/// 선택 영역 크기 변경하기
/// </summary>
private void ScaleSelectionArea()
{
this.selectedAreaScaledPointList = new List<PointF>();
foreach(PointF point in this.selectedAreaPointList)
{
this.selectedAreaScaledPointList.Add
(
new PointF
(
point.X * this.bitmapScale,
point.Y * this.bitmapScale
)
);
}
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] Bitmap 클래스 : 카툰 필터(Cartoon Filter) 사용하기 (0) | 2021.01.03 |
---|---|
[C#/WINFORM] Bitmap 클래스 : 오일 페인트 필터(Oil Paint Filter) 사용하기 (0) | 2021.01.03 |
[C#/WINFORM] Bitmap 클래스 : 이미지 추상 색상 필터 사용하기 (0) | 2021.01.03 |
[C#/WINFORM] Bitmap 클래스 : 바이트 배열 구하기 (0) | 2021.01.03 |
[C#/WINFORM] Bitmap 클래스 : 정사각형 크기 비트맵에 복사하기 (0) | 2021.01.03 |
[C#/WINFORM] Bitmap 클래스 : 크기 변경 비트맵 구하기 (0) | 2020.12.27 |
[C#/WINFORM] Bitmap 클래스 : 비트맵 파일 로드하기 (0) | 2020.12.27 |
[C#/WINFORM] Application 클래스 : SetSuspendState 정적 메소드를 사용해 절전 모드 만들기 (0) | 2020.12.27 |
[C#/WINFORM] 지정 시간 경과 후 절전 모드에서 활성화하기 (0) | 2020.12.27 |
[C#/WINFORM] Graphics 클래스 : DrawImage 메소드 사용시 이미지 어트리뷰트 설정하기 (0) | 2020.12.27 |
댓글을 달아 주세요