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

TestProject.zip
다운로드

▶ 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
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요