728x90
반응형
728x170
▶ MainForm.cs
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
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 Bitmap sourceBitmap = null;
/// <summary>
/// 타겟 비트맵
/// </summary>
private Bitmap targetBitmap = null;
/// <summary>
/// 각도
/// </summary>
private float angle = 0;
/// <summary>
/// 시작 포인트
/// </summary>
private Point startPoint = new Point(50, 100);
/// <summary>
/// 종료 포인트
/// </summary>
private Point endPoint = new Point(210, 100);
/// <summary>
/// 그리기 여부
/// </summary>
private bool isDrawing = false;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
this.openMenuItem.Click += openMenuItem_Click;
this.saveAsMenuItem.Click += saveAsMenuItem_Click;
this.exitMenuItem.Click += exitMenuItem_Click;
this.resetAngleMenuItem.Click += resetAngleMenuItem_Click;
this.drawGridMenuItem.Click += drawGridMenuItem_Click;
this.pictureBox.MouseDown += pictureBox_MouseDown;
this.pictureBox.MouseMove += pictureBox_MouseMove;
this.pictureBox.MouseUp += pictureBox_MouseUp;
this.pictureBox.Paint += pictureBox_Paint;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#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.sourceBitmap = LoadBitmapUnlocked(this.openFileDialog.FileName);
this.angle = 0;
DrawImage();
}
}
#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.targetBitmap, 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 각도 리셋 메뉴 항목 클릭시 처리하기 - resetAngleMenuItem_Click(sender, e)
/// <summary>
/// 각도 리셋 메뉴 항목 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void resetAngleMenuItem_Click(object sender, EventArgs e)
{
this.angle = 0;
this.startPoint = new Point(50, 100);
this.endPoint = new Point(210, 100);
DrawImage();
}
#endregion
#region 그리드 그리기 - drawGridMenuItem_Click(sender, e)
/// <summary>
/// 그리드 그리기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void drawGridMenuItem_Click(object sender, EventArgs e)
{
this.pictureBox.Refresh();
}
#endregion
#region 픽처 박스 마우스 DOWN 처리하기 - pictureBox_MouseDown(sender, e)
/// <summary>
/// 픽처 박스 마우스 DOWN 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
this.startPoint = e.Location;
this.endPoint = e.Location;
this.isDrawing = true;
}
#endregion
#region 픽처 박스 마우스 이동시 처리하기 - pictureBox_MouseMove(sender, e)
/// <summary>
/// 픽처 박스 마우스 이동시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if(!this.isDrawing)
{
return;
}
this.endPoint = e.Location;
this.pictureBox.Refresh();
}
#endregion
#region 픽처 박스 마우스 UP 처리하기 - pictureBox_MouseUp(sender, e)
/// <summary>
/// 픽처 박스 마우스 UP 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
this.isDrawing = false;
int deltaX = this.endPoint.X - this.startPoint.X;
int deltaY = this.endPoint.Y - this.startPoint.Y;
double newAngle = Math.Atan2(deltaY, deltaX) * 180.0 / Math.PI;
this.angle -= (float)newAngle;
DrawImage();
}
#endregion
#region 픽처 박스 페인트시 처리하기 - pictureBox_Paint(sender, e)
/// <summary>
/// 픽처 박스 페인트시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void pictureBox_Paint(object sender, PaintEventArgs e)
{
if(this.isDrawing)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawLine(Pens.Yellow, this.startPoint, this.endPoint);
using(Pen pen = new Pen(Color.Red))
{
pen.DashPattern = new float[] { 5, 5 };
e.Graphics.DrawLine(pen, this.startPoint, this.endPoint);
}
}
if(this.drawGridMenuItem.Checked)
{
const int deltaX = 50;
int maximumX = this.pictureBox.ClientSize.Width;
int maximumY = this.pictureBox.ClientSize.Height;
for(int x = 0; x < maximumX; x += deltaX)
{
e.Graphics.DrawLine(Pens.Silver, x, 0, x, maximumY);
}
for(int y = 0; y < maximumY; y += deltaX)
{
e.Graphics.DrawLine(Pens.Silver, 0, y, maximumX, y);
}
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 잠금없이 비트맵 로드하기 - LoadBitmapUnlocked(filePath)
/// <summary>
/// 잠금없이 비트맵 로드하기
/// </summary>
/// <param name="filePath">파일 경로</param>
/// <returns>비트맵</returns>
private Bitmap LoadBitmapUnlocked(string filePath)
{
using(Bitmap bitmap = new Bitmap(filePath))
{
return new Bitmap(bitmap);
}
}
#endregion
#region 이미지 저장하기 - SaveImage(image, filePath)
/// <summary>
/// 이미지 저장하기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="filePath">파일 경로</param>
public void SaveImage(Image image, string filePath)
{
string extension = Path.GetExtension(filePath);
switch(extension.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 " + extension);
}
}
#endregion
#region 이미지 그리기 - DrawImage()
/// <summary>
/// 이미지 그리기
/// </summary>
private void DrawImage()
{
if(this.sourceBitmap == null)
{
this.pictureBox.Refresh();
return;
}
int width = this.sourceBitmap.Width;
int height = this.sourceBitmap.Height;
Matrix matrix = new Matrix();
matrix.Rotate(this.angle);
PointF[] pointArray =
{
new PointF(0 , 0 ),
new PointF(width, 0 ),
new PointF(0 , height),
new PointF(width, height)
};
matrix.TransformPoints(pointArray);
float minimumX = pointArray[0].X;
float maximumX = minimumX;
float minimumY = pointArray[0].Y;
float maximumY = minimumY;
for(int i = 1; i < pointArray.Length; i++)
{
if(minimumX > pointArray[i].X) minimumX = pointArray[i].X;
if(maximumX < pointArray[i].X) maximumX = pointArray[i].X;
if(minimumY > pointArray[i].Y) minimumY = pointArray[i].Y;
if(maximumY < pointArray[i].Y) maximumY = pointArray[i].Y;
}
float newWidth = maximumX - minimumX;
float newHeight = maximumY - minimumY;
matrix.Translate(newWidth / 2, newHeight / 2, MatrixOrder.Append);
this.targetBitmap = new Bitmap((int)newWidth, (int)newHeight);
using(Graphics graphics = Graphics.FromImage(this.targetBitmap))
{
graphics.InterpolationMode = InterpolationMode.High;
graphics.Clear(Color.White);
graphics.Transform = matrix;
PointF[] targetPointArray =
{
new PointF(-width / 2, -height / 2),
new PointF( width / 2, -height / 2),
new PointF(-width / 2, height / 2)
};
graphics.DrawImage(sourceBitmap, targetPointArray);
}
this.pictureBox.Image = this.targetBitmap;
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] 다른 선 아래로 지나가는 것을 보여주기 위해 간격이 있는 선 그리기 (0) | 2020.08.06 |
---|---|
[C#/WINFORM] 미로 길 찾기 (애니메이션) (0) | 2020.08.05 |
[C#/WINFORM] 미로 길 찾기 (0) | 2020.08.05 |
[C#/WINFORM] ImageAttributes 클래스 : 이미지 수정하기 (0) | 2020.08.04 |
[C#/WINFORM] 라운드 다각형 그리기 (0) | 2020.08.03 |
[C#/WINFORM] 기준선을 사용해 이미지 회전하기 (0) | 2020.08.03 |
[C#/WINFORM] 마우스 아래 그려진 문자 찾기 (0) | 2020.08.03 |
[C#/WINFORM] 다각형 내에서 이미지 그리기 (0) | 2020.08.03 |
[C#/WINFORM] RGB 색상에서 HSV 색상 구하기 (0) | 2020.08.02 |
[C#/WINFORM] 다각형 선택자를 사용해 다각형 그리기 (0) | 2020.08.01 |
[C#/WINFORM] X/Y축 기준선에 따라 다각형 그리기 (0) | 2020.07.30 |
댓글을 달아 주세요