生成验证码的方式有很多种,如下则是比较简单的实现,且运用了正余弦曲线来扭曲验证码字符。

unit AuthenticodeGenerate;

interface

uses
SysUtils, Windows, ExtCtrls, Graphics; function GenerateAuthenticode(const Img: TImage; const Len: Integer = 4): string; implementation const
cCharDigitArrayLen = 6;
cCharDigitArray : array[0..cCharDigitArrayLen - 1] of Char = ('3', '4', '5', '6', '7', '8'); cCharLowerLetterArrayLen = 13;
cCharLowerLetterArray: array[0..cCharLowerLetterArrayLen - 1] of Char = ('b', 'c', 'e', 'h', 'j', 'k', 'm', 'n', 's', 't', 'v', 'w', 'y'); cCharUpperLetterArrayLen = 19;
cCharUpperLetterArray: array[0..cCharUpperLetterArrayLen - 1] of Char = ('A', 'B', 'C', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'V', 'W', 'Y'); cArrayTypeNum = 3; cFontNameNum = 5;
cFontNameArray: array[0..cFontNameNum - 1] of string = ('Arial', 'Tahoma', '宋体', '幼圆', '微软雅黑'); function TwistImage(const SrcBmp: TBitmap; XDir: Boolean; MultFactor: Double; Phase: Double; SinTrick: Boolean): TBitmap;
const
cTwicePi = 6.283185;
var
BaseAxisLen : Double;
I, J : Integer;
DestX, DestY: Double;
OldX, OldY : Integer;
Color : TColor;
begin
Result := TBitmap.Create;
Result.SetSize(SrcBmp.Width, SrcBmp.Height); if XDir then
BaseAxisLen := Result.Height
else
BaseAxisLen := Result.Width; for I := 0 to Result.Width - 1 do
begin
for J := 0 to Result.Height - 1 do
begin
if XDir then
DestX := (cTwicePi * J) / BaseAxisLen
else
DestX := (cTwicePi * I) / BaseAxisLen; if SinTrick then
begin
DestX := DestX + Phase;
DestY := Sin(DestX);
end else
begin
DestX := DestX + Phase;
DestY := Cos(DestX);
end; if XDir then
begin
OldX := I + Round(DestY * MultFactor);
OldY := J;
end else
begin
OldX := I;
OldY := J + Round(DestY * MultFactor);
end; Color := SrcBmp.Canvas.Pixels[I, J];
if (OldX >= 0) and (OldX < Result.Width) and (OldY >= 0) and (OldY < Result.Height) then
Result.Canvas.Pixels[OldX, OldY] := Color;
end;
end;
end; procedure NoiseImage(const Img: TImage);
const
cNoiseLineNum = 5;
cNoisePointNum = 50;
var
I: Integer;
X: Integer;
Y: Integer;
begin
for I := 0 to cNoiseLineNum - 1 do
begin
Img.Canvas.Pen.Style := psSolid; case Random(3) of
0: Img.Canvas.Pen.Color := clBlack;
1: Img.Canvas.Pen.Color := clGray;
else
Img.Canvas.Pen.Color := clSilver;
end; X := Random(Img.Width);
Y := Random(Img.Height);
Img.Canvas.MoveTo(X, Y);
Img.Canvas.LineTo(X + Random(Img.Width - X), Y + Random(Img.Height - Y));
end; for I := 0 to cNoisePointNum - 1 do
begin
case Random(3) of
0: Img.Canvas.Pixels[Random(Img.Width), Random(Img.Height)] := clBlack;
1: Img.Canvas.Pixels[Random(Img.Width), Random(Img.Height)] := clGray;
else
Img.Canvas.Pixels[Random(Img.Width), Random(Img.Height)] := clSilver;
end;
end;
end; function GenerateCharacterAuthenticode(const Img: TImage; const Len: Integer = 4): string;
var
I: Integer;
V: Char;
X: Integer;
Y: Integer;
L: Integer;
begin
Result := ''; for I := 0 to Len - 1 do
begin
case Random(cArrayTypeNum) of
0:
begin
V := cCharDigitArray[Random(cCharDigitArrayLen)];
Result := Result + V;
end;
1:
begin
V := cCharLowerLetterArray[Random(cCharLowerLetterArrayLen)];
Result := Result + V;
end;
else
begin
V := cCharUpperLetterArray[Random(cCharUpperLetterArrayLen)];
Result := Result + V;
end;
end;
end; L := 2 + Random(2);
Img.Picture := nil; for I := 0 to Length(Result) - 1 do
begin
Img.Canvas.Font.Size := Random(5) + 17;
Img.Canvas.Font.Color := RGB(Random(256) and $C0, Random(256) and $C0, Random(256) and $C0);
case Random(3) of
0: Img.Canvas.Font.Style := [fsBold];
1: Img.Canvas.Font.Style := [fsItalic];
end;
Img.Canvas.Font.Name := cFontNameArray[Random(cFontNameNum)];
X := Random(4) + L;
Y := Random(2) + 4;
Img.Canvas.TextOut(X, Y, Result[I + 1]);
L := X + Img.Canvas.TextWidth(Result[I + 1]) + Random(2);
end; if Random(2) = 0 then
begin
if Random(2) = 0 then
Img.Picture.Bitmap := TwistImage(Img.Picture.Bitmap, True, 8 + Random(3), 1 + Random(2), True)
else
Img.Picture.Bitmap := TwistImage(Img.Picture.Bitmap, False, 8 + Random(3), 1 + Random(2), True);
end else
begin
if Random(2) = 0 then
Img.Picture.Bitmap := TwistImage(Img.Picture.Bitmap, True, 8 + Random(3), 1 + Random(2), False)
else
Img.Picture.Bitmap := TwistImage(Img.Picture.Bitmap, False, 8 + Random(3), 1 + Random(2), False);
end; NoiseImage(Img);
end; function GenerateAuthenticode(const Img: TImage; const Len: Integer): string;
begin
Result := GenerateCharacterAuthenticode(Img, Len);
end; initialization
Randomize; end.

调用很简单:

uses
AuthenticodeGenerate; procedure TfrmMain.btnTestClick(Sender: TObject);
begin
lbl1.Caption := GenerateAuthenticode(img1);
end;

于是就有:

注:

1)、为减少识别难度,去掉了几个不易识别的字符如 1、I 等;

2)、验证码背景色当然也可以(应该)随机。

http://www.cnblogs.com/ecofast/p/4224016.html

验证码生成器(在TImage.Canvas上写字,很好看)的更多相关文章

  1. 【自己给自己题目做】:如何在Canvas上实现魔方效果

    最终demo -> 3d魔方 体验方法: 浮动鼠标找到合适的位置,按空格键暂停 选择要翻转的3*3模块,找到相邻两个正方体,鼠标点击第一个正方体,并且一直保持鼠标按下的状态直到移到第二个正方体后 ...

  2. VB编写的验证码生成器

    验证码(CAPTCHA)是“Completely AutomatedPublicTuring test to tell Computers andHumansApart”(全自动区分计算机和人类的图灵 ...

  3. JavaUtil_04_验证码生成器

    一.原理 验证码其实就是随机串.原理上可分为两种: 1.简单的验证码 直接通过字母和数字的ASCII码生成.本文采用的验证码就是这种. 2.复杂的验证码 通过一个随机串,一个指定串(如accesske ...

  4. 使用JavaScript在Canvas上画出一片星空

    随着Html5的迅猛发展,画布也变得越来越重要.下面我就写一个关于在canvas上画出一片星空的简单的代码的示例. 理论基础 初始化一个canvas,获得一个用于绘制图形的上下文环境context.并 ...

  5. canvas上的像素操作(图像复制,细调)

    canvas上的像素操作(图像复制,细调) 总结 1.操作对象:ImageData 对象,其实是canvas的像素点集合 2.主要操作: var obj=ctx.getImageData(0,0,10 ...

  6. [Ruby on Rails系列]6、一个简单的暗语生成器与解释器(上)

    [0]Ruby on Rails 系列回顾 [Ruby on Rails系列]1.开发环境准备:Vmware和Linux的安装 [Ruby on Rails系列]2.开发环境准备:Ruby on Ra ...

  7. Canvas上绘制几何图形

    重要的类自定义View组件要重写View组件的onDraw(Canvase)方法,接下来是在该 Canvas上绘制大量的几何图形,点.直线.弧.圆.椭圆.文字.矩形.多边形.曲线.圆角矩形,等各种形状 ...

  8. phpmyadmin-您可能正在上传很大的文件,请参考文档来寻找解决方法

    phpmyadmin-您可能正在上传很大的文件,请参考文档来寻找解决方法   实这个很简单的只要更改php.ini里三个配置即可.(见下面加粗部分,改成你自己的需求即可) ; Maximum allo ...

  9. 从底层谈WebGIS 原理设计与实现(六):WebGIS中地图瓦片在Canvas上的拼接显示原理

    从底层谈WebGIS 原理设计与实现(六):WebGIS中地图瓦片在Canvas上的拼接显示原理 作者:naaoveGI…    文章来源:naaoveGIS    点击数:1145    更新时间: ...

随机推荐

  1. N 个互异数的数组的平均逆序数

    N 个互异数的数组的平均逆序数为 N(N−1)/4 1. 简单证明 对于任意的数的表 L(5,8,9,6,4),以及其反序表 Lr(4,6,9,8,5),它们各自的逆序数分别为:6 ((5, 4), ...

  2. range 的实现细节(start、end、step)(左闭右开区间)

    range(int start, int end, int step); 返回的区间是 [start, end) 要求步长为 step,三个参数均为整数, 在底层实现时,最终返回的区间元素的数目应当为 ...

  3. DDD实战5 实现上下文服务

    通过服务来协调领域对象,来添加产品用例. 1.要实现产品上下文的服务,首先新建一个项目,在Product解决方案文件夹下面新建一个项目,项目的名称为:Product.AppSrv. 2.这个项目首先引 ...

  4. 李开复:VC看不上你的五个原因

    [编者按]:此文是李开复先生发表于其LinkedIn主页上的一篇文章,简单列举了五条与VC接触常忽略的经验.如果你是一位正准备和VC谈判取得资金上帮助的创业者,那么应该避免企业家常常犯下的五条错误. ...

  5. 使用python移动飞信模块发送短信

    作者:miaoo 1.应用场景 由于自己做的一个系统需要用到发送短信到自己手机的功能,于是搜索了一下,发现了一个通过移动飞信通道发送短信开源库:PyFetion PyFetion 模拟实现了飞信的通信 ...

  6. ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Razor 编辑表单 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Razor 编辑表单 上一章节我们介绍了标签助手和 HT ...

  7. CentOS6.5优盘安装

    从CentOS6.5开始直接把iso文件写入u盘就可实现优盘安装 windows平台:1.用UltraISO打开iso(如:CentOS-6.5-x86_64-bin-DVD1.iso)2.然后点“启 ...

  8. SDL(01-10)

    SDL中的函数需要先初始化SDL才能用 : //Initialize SDL ) { printf( "SDL could not initialize! SDL_Error: %s\n&q ...

  9. wpf窗体定位

    原文:wpf窗体定位 据WPF外包小编了解,通常,不需要在屏幕上明确定位窗口.而是简单地将WindowState属性设置为Normal,并忽略其他所有细节.另一方面,很少会将WindowStartup ...

  10. SQL logic error or missing database no such table: xxx

    原文:SQL logic error or missing database no such table: xxx System.Data.SQLite.SQLiteException (0x8000 ...