checkimage.aspx Page_Load 完整程式碼
// 1. 產生隨機驗證碼文字 (4-6 碼)
Random rand = new Random();
int len = rand.Next(4, 6);
char[] chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) sb.Append(chars[rand.Next(chars.Length)]);
string text = sb.ToString();
// 2. 存入 Session
Session["checkcode"] = text;
// 3. 計算圖片尺寸
Size imgSize = Size.Empty;
Font font = new Font("MS Sans Serif", 20);
using (Bitmap tmp = new Bitmap(10, 10))
using (Graphics g = Graphics.FromImage(tmp))
{
SizeF sz = g.MeasureString(text, font, 10000);
imgSize.Width = (int)sz.Width + 8;
imgSize.Height = (int)sz.Height + 8;
}
// 4. 建立正式圖片並繪製文字
using (Bitmap bmp = new Bitmap(imgSize.Width, imgSize.Height))
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
using (StringFormat fmt = new StringFormat())
{
fmt.Alignment = StringAlignment.Near;
fmt.LineAlignment = StringAlignment.Center;
fmt.FormatFlags = StringFormatFlags.NoWrap;
g.DrawString(text, font, Brushes.Black, new RectangleF(0, 0, imgSize.Width, imgSize.Height), fmt);
}
// 5. 製造雜點 (30% 面積)
int noiseCount = imgSize.Width * imgSize.Height * 30 / 100;
for (int i = 0; i < noiseCount; i++)
{
int x = rand.Next(imgSize.Width);
int y = rand.Next(imgSize.Height);
Color c = Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256));
bmp.SetPixel(x, y, c);
}
// 6. 輸出 PNG
using (MemoryStream ms = new MemoryStream())
{
bmp.Save(ms, ImageFormat.Png);
Response.ContentType = "image/png";
ms.WriteTo(Response.OutputStream);
}
}
font.Dispose();
關鍵技術點
- 雙階段建立 Bitmap:先小圖量測文字尺寸,再建立正確尺寸圖片。
StringFormat 控制對齊與換行行為。
- 雜點直接操作
SetPixel,簡單但效能較低;大量雜點可考慮 LockBits。
- 所有可釋放資源 (
Bitmap, Graphics, Font, MemoryStream) 均使用 using 確保釋放。