+ UIVerificationCode: 增加验证码控件

This commit is contained in:
Sunny 2022-06-11 11:01:27 +08:00
parent e415486a50
commit f02080876e

View File

@ -0,0 +1,167 @@
/******************************************************************************
* SunnyUI
* CopyRight (C) 2012-2022 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.dll can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : UIVerificationCode.cs
* :
* : V3.1
* : 2022-06-11
*
* 2022-06-11: V3.1.9
******************************************************************************/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Sunny.UI
{
[DefaultEvent("Click")]
[DefaultProperty("Text")]
[ToolboxItem(true)]
public class UIVerificationCode : UIControl
{
public UIVerificationCode()
{
SetStyleFlags();
fillColor = UIStyles.Blue.PlainColor;
Width = 100;
Height = 35;
}
public override void SetStyleColor(UIBaseStyle uiColor)
{
base.SetStyleColor(uiColor);
fillColor = uiColor.PlainColor;
}
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
Invalidate();
}
protected override void OnPaintFill(Graphics g, GraphicsPath path)
{
base.OnPaintFill(g, path);
var bmp = CreateImage(RandomEx.RandomChars(CodeLength));
g.DrawImage(bmp, Width / 2 - bmp.Width / 2, 1);
bmp.Dispose();
}
protected override void OnPaintFore(Graphics g, GraphicsPath path)
{
if (Text != "") Text = "";
//base.OnPaintFore(g, path);
}
[DefaultValue(4)]
[Description("验证码长度"), Category("SunnyUI")]
public int CodeLength { get; set; } = 4;
[DefaultValue(18)]
[Description("验证码字体大小"), Category("SunnyUI")]
public int CodeFontSize { get; set; } = 18;
[DefaultValue(null)]
[Description("验证码文字"), Category("SunnyUI")]
public string Code { get; private set; }
/// <summary>
/// 生成图片
/// </summary>
/// <param name="code">验证码表达式</param>
private Bitmap CreateImage(string code)
{
Font font = new Font(Font.Name, CodeFontSize);
Code = code;
SizeF sf = GDI.MeasureString(code, font);
Bitmap image = new Bitmap((int)sf.Width + 16, Height - 2);
//创建画布
Graphics g = Graphics.FromImage(image);
Random random = new Random();
//图片背景色
g.Clear(fillColor);
//画图片背景线
for (int i = 0; i < 6; i++)
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine(Pens.Black, x1, y1, x2, y2);
}
//画图片的前景噪音点
for (int i = 0; i < 50; i++)
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
g.DrawString(code, font, rectColor, image.Width / 2 - sf.Width / 2, image.Height / 2 - sf.Height / 2);
var imageex = TwistImage(image, true, 5, 5);
font.Dispose();
image.Dispose();
return imageex;
}
///<summary>
///正弦曲线Wave扭曲图片
///</summary>
///<param name="srcBmp">图片路径</param>
///<param name="bXDir">如果扭曲则选择为True</param>
///<param name="nMultValue">波形的幅度倍数越大扭曲的程度越高一般为3</param>
///<param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
///<returns></returns>
private Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
{
Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
// 将位图背景填充为白色
Graphics graph = Graphics.FromImage(destBmp);
graph.FillRectangle(new SolidBrush(fillColor), 0, 0, destBmp.Width, destBmp.Height);
graph.Dispose();
double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width;
for (int i = 0; i < destBmp.Width; i++)
{
for (int j = 0; j < destBmp.Height; j++)
{
double dx = 0;
dx = bXDir ? (Math.PI * 2 * (double)j) / dBaseAxisLen : (Math.PI * 2 * (double)i) / dBaseAxisLen;
dx += dPhase;
double dy = Math.Sin(dx);
// 取得当前点的颜色
int nOldX = 0, nOldY = 0;
nOldX = bXDir ? i + (int)(dy * dMultValue) : i;
nOldY = bXDir ? j : j + (int)(dy * dMultValue);
System.Drawing.Color color = srcBmp.GetPixel(i, j);
if (nOldX >= 0 && nOldX < destBmp.Width && nOldY >= 0 && nOldY < destBmp.Height)
{
destBmp.SetPixel(nOldX, nOldY, color);
}
}
}
return destBmp;
}
}
}