The Piece of Code

[C#] Captcha

fonch 2016. 2. 10. 11:42

C#으로 Captcha(https://ko.wikipedia.org/wiki/CAPTCHA) 를 구현하는 코드입니다.

Google 의 reCaptchar(https://developers.google.com/recaptcha/) 같은 api를 통해서도 spam 이나 bot을 막아주는 비슷한 같은 목적의 개발이 가능합니다.


Code Project(http://www.codeproject.com/) 에서 참고하였던 Code를 함수로 제가 쓰기 쉽게 조금 수정한 Code입니다.

(결과는 참고페이지 참고)


using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;

public MemoryStream GenerateCaptchaImage(string captchaText, int width = 190, int height = 80)
{
	int iWidth = width;
	int iHeight = height;
	Random oRandom = new Random();

	int[] aBackgroundNoiseColor = new int[] { 150, 150, 150 };
	int[] aTextColor = new int[] { 0, 0, 0 };
	int[] aFontEmSizes = new int[] { 15, 20, 25, 30, 35 };

	string[] aFontNames = new string[]
	{
			"Comic Sans MS",
			"Arial",
			"Times New Roman",
			"Georgia",
			"Verdana",
			"Geneva"
	};
	FontStyle[] aFontStyles = new FontStyle[]
	{
			FontStyle.Bold,
			FontStyle.Italic,
			FontStyle.Regular,
			FontStyle.Strikeout,
			FontStyle.Underline
	};
	HatchStyle[] aHatchStyles = new HatchStyle[]
	{
		HatchStyle.BackwardDiagonal,
		HatchStyle.Cross,
		HatchStyle.DashedDownwardDiagonal,
		HatchStyle.DashedHorizontal,
		HatchStyle.DashedUpwardDiagonal,
		HatchStyle.DashedVertical,
		HatchStyle.DiagonalBrick,
		HatchStyle.DiagonalCross,
		HatchStyle.Divot,
		HatchStyle.DottedDiamond,
		HatchStyle.DottedGrid,
		HatchStyle.ForwardDiagonal,
		HatchStyle.Horizontal,
		HatchStyle.HorizontalBrick,
		HatchStyle.LargeCheckerBoard,
		HatchStyle.LargeConfetti,
		HatchStyle.LargeGrid,
		HatchStyle.LightDownwardDiagonal,
		HatchStyle.LightHorizontal,
		HatchStyle.LightUpwardDiagonal,
		HatchStyle.LightVertical,
		HatchStyle.Max,
		HatchStyle.Min,
		HatchStyle.NarrowHorizontal,
		HatchStyle.NarrowVertical,
		HatchStyle.OutlinedDiamond,
		HatchStyle.Plaid,
		HatchStyle.Shingle,
		HatchStyle.SmallCheckerBoard,
		HatchStyle.SmallConfetti,
		HatchStyle.SmallGrid,
		HatchStyle.SolidDiamond,
		HatchStyle.Sphere,
		HatchStyle.Trellis,
		HatchStyle.Vertical,
		HatchStyle.Wave,
		HatchStyle.Weave,
		HatchStyle.WideDownwardDiagonal,
		HatchStyle.WideUpwardDiagonal,
		HatchStyle.ZigZag
	};

	//
	// Creates an output Bitmap
	using (Bitmap oOutputBitmap = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb))
	{
		using (Graphics oGraphics = Graphics.FromImage(oOutputBitmap))
		{
			oGraphics.TextRenderingHint = TextRenderingHint.AntiAlias;

			//
			// Create a Drawing area
			RectangleF oRectangleF = new RectangleF(0, 0, iWidth, iHeight);
			Brush oBrush = default(Brush);

			//
			// Draw background (Lighter colors RGB 100 to 255)
			// => 배경색 설정
			oBrush = new HatchBrush(aHatchStyles[oRandom.Next(aHatchStyles.Length - 1)],
										Color.FromArgb((oRandom.Next(100, 255)),
											(oRandom.Next(100, 255)),
											(oRandom.Next(100, 255))
										),
										Color.White);
			oGraphics.FillRectangle(oBrush, oRectangleF);

			Matrix oMatrix = new Matrix();
			int i = 0;
			for (i = 0; i <= captchaText.Length - 1; i++)
			{
				oMatrix.Reset();
				int iChars = captchaText.Length;

				int x = iWidth / (iChars + 1) * i;
				int y = iHeight / 2;

				//
				// Rotate text Random
				// => Output Text 회전
				oMatrix.RotateAt(oRandom.Next(-40, 40), new PointF(x, y));
				oGraphics.Transform = oMatrix;

				//
				// Draw the letters with Random Font Type, Size and Color
				// => Font의 Type, Size, Color 를 Random으로 설저하여 한단어씩 그림
				oGraphics.DrawString
				(
					//Text
					captchaText.Substring(i, 1),
					//Random Font Name and Style
					new Font(aFontNames[oRandom.Next(aFontNames.Length - 1)], 
							aFontEmSizes[oRandom.Next(aFontEmSizes.Length - 1)],
							aFontStyles[oRandom.Next(aFontStyles.Length - 1)]
					),
					//Random Color (Darker colors RGB 0 to 100)
					new SolidBrush(
						Color.FromArgb(oRandom.Next(0, 100),
										oRandom.Next(0, 100),
										oRandom.Next(0, 100)
									)
					),
					x,
					oRandom.Next(10, 40)
				);
				oGraphics.ResetTransform();
			}

			MemoryStream oMemoryStream = new MemoryStream();
			oOutputBitmap.Save(oMemoryStream, ImageFormat.Png);

			//
			// Stream 으로 반환하거나 Image 그대로 반환하여 사용.
			// return oOutputBitmap; // => return Image (oOutputBitmap의 using 문 제거후 사용해야 함)
			// return oMemoryStream; // => return Stream
			// return oMemoryStream.GetBuffer(); // => return Byte[]
			return oMemoryStream;
		}
	}
}

$참고: http://www.codeproject.com/Articles/99148/Simple-CAPTCHA-Create-your-own-in-C

'The Piece of Code' 카테고리의 다른 글

[C#] Image Resize - ASP.NET  (0) 2016.02.10
[C#] Image Resize - Winfrom  (0) 2016.02.10
[CSS] margin, pdding 순서  (0) 2015.02.03
[javascript] 모바일 기기 구분하기  (0) 2013.02.28
[C#] StripHtml  (1) 2013.01.20