Delphi 開發登錄界面,需生成圖形驗證碼(含干擾線、噪點、字符旋轉、顏色隨機),防止自動化腳本暴力破解。
const Chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'。TBitmap,設定寬高 (如 120x40),背景填充隨機淺色或漸變。TextOut 繪制到臨時 TBitmap (單字符畫布)。Rotate (需自行實現或用 PlgBlt/SetWorldTransform + XFORM 矩陣)。CopyRect/Draw 到主驗證碼圖片,X 位置遞增並加隨機偏移。Canvas.MoveTo/LineTo,隨機顏色/寬度/虛線樣式。Canvas.Pixels[X,Y] := RandomColor 或填充隨機小矩形。Session (Web) 或全局變量/數據庫 (C/S),設置過期時間 (如 5 分鐘)。Bitmap.SaveToStream → JPEG/PNG 流 → HTTP 響應 / TImage.Picture 顯示。SetWorldTransform)uses Graphics, Math, Windows;
procedure DrawRotatedText(Canvas: TCanvas; const S: string; X, Y: Integer; Angle: Double; FontColor: TColor);
var
XForm: TXForm;
OldMode: Integer;
LogFont: TLogFont;
begin
Canvas.Font.Color := FontColor;
GetObject(Canvas.Font.Handle, SizeOf(LogFont), @LogFont);
LogFont.lfEscapement := Round(Angle * 10); // 0.1 度單位
LogFont.lfOrientation := LogFont.lfEscapement;
Canvas.Font.Handle := CreateFontIndirect(LogFont);
OldMode := SetGraphicsMode(Canvas.Handle, GM_ADVANCED);
try
Canvas.TextOut(X, Y, S);
finally
SetGraphicsMode(Canvas.Handle, OldMode);
// 恢復字體
end;
end;
procedure AddNoise(Canvas: TCanvas; Width, Height: Integer);
var
i: Integer;
begin
// 干擾線
Canvas.Pen.Width := Random(2) + 1;
for i := 1 to Random(3) + 2 do begin
Canvas.Pen.Color := RandomColor;
Canvas.Pen.Style := TPenStyle(Random(3)); // psSolid, psDash, psDot
Canvas.MoveTo(Random(Width), Random(Height));
Canvas.LineTo(Random(Width), Random(Height));
end;
// 噪點
for i := 1 to Random(100) + 50 do
Canvas.Pixels[Random(Width), Random(Height)] := RandomColor;
end;
function RandomColor: TColor;
begin
Result := RGB(Random(200), Random(200), Random(200)); // 避免純白/純黑
end;
function GenerateCaptcha(var Code: string; Width, Height: Integer): TBitmap;
const
CharSet = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
var
Bmp, CharBmp: TBitmap;
i, CharCount, XPos: Integer;
Ch: Char;
Angle: Double;
begin
Code := '';
CharCount := 4 + Random(2); // 4-5 位
Bmp := TBitmap.Create;
try
Bmp.Width := Width;
Bmp.Height := Height;
Bmp.PixelFormat := pf24bit;
// 背景
Bmp.Canvas.Brush.Color := RGB(230 + Random(25), 230 + Random(25), 230 + Random(25));
Bmp.Canvas.FillRect(Rect(0, 0, Width, Height));
XPos := 10;
for i := 1 to CharCount do begin
Ch := CharSet[Random(Length(CharSet)) + 1];
Code := Code + Ch;
CharBmp := TBitmap.Create;
try
CharBmp.Width := 30;
CharBmp.Height := Height;
CharBmp.Canvas.Brush.Style := bsClear;
CharBmp.Canvas.Font.Size := 20 + Random(6);
CharBmp.Canvas.Font.Style := [fsBold];
CharBmp.Canvas.Font.Color := RandomColor;
CharBmp.Canvas.TextOut(0, 0, Ch);
Angle := (Random(60) - 30) * Pi / 180; // -30°~+30°
// 這裡需用 PlgBlt 或 SetWorldTransform 旋轉 CharBmp 到 Bmp
// 簡化示意:直接 TextOut + 旋轉字體 (見上方 DrawRotatedText)
DrawRotatedText(Bmp.Canvas, Ch, XPos, 5, Angle * 180 / Pi, RandomColor);
finally
CharBmp.Free;
end;
XPos := XPos + 22 + Random(8); // 字符間距
end;
AddNoise(Bmp.Canvas, Width, Height);
Result := Bmp;
except
Bmp.Free;
raise;
end;
end;
Delphi 生成驗證碼核心在於:字符隨機化 + 幾何變換(旋轉/扭曲) + 干擾元素疊加 + 服務端強驗證。上述代碼框架可直接集成到 VCL/FMX 項目,配合 TIdHTTPServer (Indy) 或 WebBroker 輸出圖片流。若項目允許,強烈建議接入成熟驗證碼服務,安全性與維護性雙贏。