验证码生成器(在TImage.Canvas上写字,很好看)
生成验证码的方式有很多种,如下则是比较简单的实现,且运用了正余弦曲线来扭曲验证码字符。

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上写字,很好看)的更多相关文章
- 【自己给自己题目做】:如何在Canvas上实现魔方效果
最终demo -> 3d魔方 体验方法: 浮动鼠标找到合适的位置,按空格键暂停 选择要翻转的3*3模块,找到相邻两个正方体,鼠标点击第一个正方体,并且一直保持鼠标按下的状态直到移到第二个正方体后 ...
- VB编写的验证码生成器
验证码(CAPTCHA)是“Completely AutomatedPublicTuring test to tell Computers andHumansApart”(全自动区分计算机和人类的图灵 ...
- JavaUtil_04_验证码生成器
一.原理 验证码其实就是随机串.原理上可分为两种: 1.简单的验证码 直接通过字母和数字的ASCII码生成.本文采用的验证码就是这种. 2.复杂的验证码 通过一个随机串,一个指定串(如accesske ...
- 使用JavaScript在Canvas上画出一片星空
随着Html5的迅猛发展,画布也变得越来越重要.下面我就写一个关于在canvas上画出一片星空的简单的代码的示例. 理论基础 初始化一个canvas,获得一个用于绘制图形的上下文环境context.并 ...
- canvas上的像素操作(图像复制,细调)
canvas上的像素操作(图像复制,细调) 总结 1.操作对象:ImageData 对象,其实是canvas的像素点集合 2.主要操作: var obj=ctx.getImageData(0,0,10 ...
- [Ruby on Rails系列]6、一个简单的暗语生成器与解释器(上)
[0]Ruby on Rails 系列回顾 [Ruby on Rails系列]1.开发环境准备:Vmware和Linux的安装 [Ruby on Rails系列]2.开发环境准备:Ruby on Ra ...
- Canvas上绘制几何图形
重要的类自定义View组件要重写View组件的onDraw(Canvase)方法,接下来是在该 Canvas上绘制大量的几何图形,点.直线.弧.圆.椭圆.文字.矩形.多边形.曲线.圆角矩形,等各种形状 ...
- phpmyadmin-您可能正在上传很大的文件,请参考文档来寻找解决方法
phpmyadmin-您可能正在上传很大的文件,请参考文档来寻找解决方法 实这个很简单的只要更改php.ini里三个配置即可.(见下面加粗部分,改成你自己的需求即可) ; Maximum allo ...
- 从底层谈WebGIS 原理设计与实现(六):WebGIS中地图瓦片在Canvas上的拼接显示原理
从底层谈WebGIS 原理设计与实现(六):WebGIS中地图瓦片在Canvas上的拼接显示原理 作者:naaoveGI… 文章来源:naaoveGIS 点击数:1145 更新时间: ...
随机推荐
- Centos root权限的变化
方法一:更改 /etc/sudoers 文件, 找到以下一行,把前面的凝视(#)去掉 ## Allows people in group wheel to run all commands %whee ...
- [Spring Boot 系列] 集成maven和Spring boot的profile 专题
maven中配置profile节点: <project> .... <profiles> <profile> <!-- 生产环境 --> <id& ...
- LeetCode总结 -- 树结构的一部分
这篇总结主要介绍树中比較常见的一类题型--树的构造.事实上本质还是用递归的手法来实现,可是这类题目有一个特点.就是它是构建一棵树.而不是给定一棵树,然后进行遍历,所以实现起来思路上有点逆向,还是要练习 ...
- $.extend(true,{},a,b)解析
原文:$.extend(true,{},a,b)解析 版权声明: https://blog.csdn.net/bsfz_2018/article/details/81738437 什么是$.exten ...
- uwp - 解决“Microsoft.EntityFrameworkCore.Tools –Pre因为在此系统上禁止运行脚本”
在uwp使用ef时,需要安装“Microsoft.EntityFrameworkCore.Tools –Pre” ,如果安装失败提示:“无法加载文件 \.nuget\packages\Microsof ...
- 零元学Expression Design 4 - Chapter 2 熟悉Design并且快速设计出Silverlight网页
原文:零元学Expression Design 4 - Chapter 2 熟悉Design并且快速设计出Silverlight网页 本章将用带大家熟悉Design 4并制作简易的网页版面,也会让你了 ...
- WPF用Blend写的交通信号灯
原文:WPF用Blend写的交通信号灯 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/details/1 ...
- HTML精确定位:scrollLeft,scrollWidth,clientWidth,offsetWidth完全详细的说明
HTML:scrollLeft,scrollWidth,clientWidth,offsetWidth具体指完全解释究竟哪里的距离scrollHeight: 获取对象的高度滚动. scrollLe ...
- css 浏览器兼容性问题解决
一个.!important (功能有限) 随着IE7正确!important支持, !important 方法现在只IE6兼容.(注意措辞.我记得这句话需要推进的位置.) : #example ...
- FFmpeg来源简单分析:结构会员管理系统-AVClass
===================================================== FFmpeg章列表: [架构图] FFmpeg源码结构图 - 解码 FFmpeg源码结构图 ...