728x90
반응형
728x170
▶ BitmapHelper.cs
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace TestProject
{
/// <summary>
/// 비트맵 헬퍼
/// </summary>
public static class BitmapHelper
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 비트맵 로드하기 - LoadBitmap(filePath)
/// <summary>
/// 비트맵 로드하기
/// </summary>
/// <param name="filePath">파일 경로</param>
/// <returns>비트맵</returns>
public static Bitmap LoadBitmap(string filePath)
{
using(Bitmap bitmap = new Bitmap(filePath))
{
return new Bitmap(bitmap);
}
}
#endregion
#region 비트맵 회전하기 - RotateBitmap(sourceBitmap, angleBlue, angleGreen, angleRed)
/// <summary>
/// 비트맵 회전하기
/// </summary>
/// <param name="sourceBitmap">소스 비트맵</param>
/// <param name="angleBlue">청색 채널 각도</param>
/// <param name="angleGreen">녹색 채널 각도</param>
/// <param name="angleRed">적색 채널 각도</param>
/// <returns>비트맵</returns>
public static Bitmap RotateBitmap(Bitmap sourceBitmap, double angleBlue, double angleGreen, double angleRed)
{
BitmapData sourceBitmapData = sourceBitmap.LockBits
(
new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb
);
byte[] sourceByteArray = new byte[sourceBitmapData.Stride * sourceBitmapData.Height];
byte[] targetByteArray = new byte[sourceBitmapData.Stride * sourceBitmapData.Height];
Marshal.Copy(sourceBitmapData.Scan0, sourceByteArray, 0, sourceByteArray.Length);
sourceBitmap.UnlockBits(sourceBitmapData);
angleBlue = angleBlue * Math.PI / 180.0;
angleGreen = angleGreen * Math.PI / 180.0;
angleRed = angleRed * Math.PI / 180.0;
int xOffset = (int )(sourceBitmap.Width / 2.0);
int yOffset = (int )(sourceBitmap.Height / 2.0);
int sourceXY = 0;
int targetXY = 0;
Point sourcePoint = new Point();
Point targetPoint = new Point();
Rectangle sourceRectangle = new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height);
for(int y = 0; y < sourceBitmap.Height; y++)
{
for(int x = 0; x < sourceBitmap.Width; x++)
{
sourceXY = y * sourceBitmapData.Stride + x * 4;
sourcePoint.X = x;
sourcePoint.Y = y;
if(sourceXY >= 0 && sourceXY + 3 < sourceByteArray.Length)
{
targetPoint = RotateXY(sourcePoint, angleBlue, xOffset, yOffset);
targetXY = (int)(Math.Round((targetPoint.Y * sourceBitmapData.Stride) + (targetPoint.X * 4.0)));
if(sourceRectangle.Contains(targetPoint) && targetXY >= 0)
{
if(targetXY + 6 < targetByteArray.Length)
{
targetByteArray[targetXY + 4] = sourceByteArray[sourceXY];
targetByteArray[targetXY + 7] = 255;
}
if(targetXY + 3 < targetByteArray.Length)
{
targetByteArray[targetXY] = sourceByteArray[sourceXY];
targetByteArray[targetXY + 3] = 255;
}
}
targetPoint = RotateXY(sourcePoint, angleGreen, xOffset, yOffset);
targetXY = (int)(Math.Round((targetPoint.Y * sourceBitmapData.Stride) + (targetPoint.X * 4.0)));
if(sourceRectangle.Contains(targetPoint) && targetXY >= 0)
{
if(targetXY + 6 < targetByteArray.Length)
{
targetByteArray[targetXY + 5] = sourceByteArray[sourceXY + 1];
targetByteArray[targetXY + 7] = 255;
}
if(targetXY + 3 < targetByteArray.Length)
{
targetByteArray[targetXY + 1] = sourceByteArray[sourceXY + 1];
targetByteArray[targetXY + 3] = 255;
}
}
targetPoint = RotateXY(sourcePoint, angleRed, xOffset, yOffset);
targetXY = (int)(Math.Round((targetPoint.Y * sourceBitmapData.Stride) + (targetPoint.X * 4.0)));
if(sourceRectangle.Contains(targetPoint) && targetXY >= 0)
{
if(targetXY + 6 < targetByteArray.Length)
{
targetByteArray[targetXY + 6] = sourceByteArray[sourceXY + 2];
targetByteArray[targetXY + 7] = 255;
}
if(targetXY + 3 < targetByteArray.Length)
{
targetByteArray[targetXY + 2] = sourceByteArray[sourceXY + 2];
targetByteArray[targetXY + 3] = 255;
}
}
}
}
}
Bitmap targetBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height);
BitmapData targetBitmapData = targetBitmap.LockBits
(
new Rectangle (0, 0, targetBitmap.Width, targetBitmap.Height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb
);
Marshal.Copy(targetByteArray, 0, targetBitmapData.Scan0, targetByteArray.Length);
targetBitmap.UnlockBits(targetBitmapData);
return targetBitmap;
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Private
#region XY 회전하기 - RotateXY(sourcePoint, radianAngle, offsetX, offsetY)
/// <summary>
/// XY 회전하기
/// </summary>
/// <param name="sourcePoint">소스 포인트</param>
/// <param name="radianAngle">라디안 각도</param>
/// <param name="offsetX">오프셋 X</param>
/// <param name="offsetY">오프셋 Y</param>
/// <returns>포인트</returns>
private static Point RotateXY(Point sourcePoint, double radianAngle, int offsetX, int offsetY)
{
Point targetPoint = new Point();
targetPoint.X = (int)(Math.Round((sourcePoint.X - offsetX) * Math.Cos(radianAngle) - (sourcePoint.Y - offsetY) * Math.Sin(radianAngle))) + offsetX;
targetPoint.Y = (int)(Math.Round((sourcePoint.X - offsetX) * Math.Sin(radianAngle) + (sourcePoint.Y - offsetY) * Math.Cos(radianAngle))) + offsetY;
return targetPoint;
}
#endregion
}
}
728x90
▶ MainForm.cs
using System.Drawing;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
Bitmap sourceBitmap = BitmapHelper.LoadBitmap("IMAGE\\sample.jpg");
Bitmap targetBitmap = BitmapHelper.RotateBitmap(sourceBitmap, 10, 20, 30);
this.pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
this.pictureBox.Image = targetBitmap;
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] Bitmap 클래스 : 선명 가장자리 탐지 필터(Sharpen Edge Detection Filter) 사용하기 (0) | 2021.01.09 |
---|---|
[C#/WINFORM] 가우시안 커널(Gaussian Kernel) 계산하기 (0) | 2021.01.09 |
[C#/WINFORM] Bitmap 클래스 : 회색조 비트맵 구하기 (0) | 2021.01.08 |
[C#/WINFORM] Bitmap 클래스 : 투명 비트맵 구하기 (0) | 2021.01.08 |
[C#/WINFORM] Bitmap 클래스 : 불선명 필터(Blur Filter) 사용하기 (0) | 2021.01.08 |
[C#/WINFORM] Bitmap 클래스 : 비트맵 자르기(Shear) (0) | 2021.01.08 |
[C#/WINFORM] Bitmap 클래스 : 컴파스 가장자리 탐지 필터(Compass Edge Detection Filter) 사용하기 (0) | 2021.01.04 |
[C#/WINFORM] Bitmap 클래스 : 스테인 글라스 필터(Stained Glass Filter) 사용하기 (0) | 2021.01.04 |
[C#/WINFORM] Bitmap 클래스 : 경계 추출 필터(Boundary Extraction Filter) 사용하기 (0) | 2021.01.03 |
[C#/WINFORM] Bitmap 클래스 : 카툰 필터(Cartoon Filter) 사용하기 (0) | 2021.01.03 |
댓글을 달아 주세요