最近、仕事でページ検証コード機能を開発するというタスクを受けました。オンライン情報を参考にして、これまでの描画知識と組み合わせて、次のソリューションを実装しました。生成された確認コードは次のようになります。
解決すべき問題:
1. 画像をランダムに生成して System.Drawing.Bitmap オブジェクトを生成し、System.Drawing.Graphics を使用してビットマップ オブジェクトに描画する
方法
。 2. WebService メソッドのパラメータを通じて画像データを渡してBitmap オブジェクトをバイト ストリームに出力する
方法
。WebMothod はバイト配列を使用してバイト ストリームを返します。例:
1. VS.NET 2003 を使用して ASP.NET Web サービス プロジェクトを作成します。デフォルトのサービス名は MyService で、GenerateVerifyImage という名前の WebMethod が MyService に追加されます。このメソッドのコードは次のとおりです。
/// <summary>
/// 画像検証コードを生成する
/// </概要>
/// <param name="nLen">確認コードの長さ</param>
/// <param name="strKey">出力パラメータ、検証コードの内容</param>
/// <returns>画像バイト ストリーム</returns>
[ウェブメソッド]
public byte[] GenerateVerifyImage(int nLen,ref string strKey)
{
int nBmpWidth = 13*nLen+5;
int nBmpHeight = 25;
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(nBmpWidth,nBmpHeight)
// 1. ランダムな背景色を生成します。
int nRed,nGreen,nBlue // 背景の 3 値の色。
System.Random rd = new Random((int)System.DateTime.Now.Ticks);
nRed = rd.Next(255)%128+128;
nGreen = rd.Next(255)%128+128;
nBlue = rd.Next(255)%128+128;
// 2. ビットマップの背景を塗りつぶします。
System.Drawing.Graphics グラフ = System.Drawing.Graphics.FromImage(bmp);
graph.FillRectangle(new SolidBrush(System.Drawing.Color.FromArgb(nRed,nGreen,nBlue))
,0
,0
,nBmp幅
,nBmpHeight);
// 3. 背景より少し暗い色を使用して干渉線を描画します
int nLines = 3;
System.Drawing.Pen ペン = 新しい System.Drawing.Pen(System.Drawing.Color.FromArgb(nRed-17,nGreen-17,nBlue-17),2);
for(int a =0;a< nLines;a++)
{
int x1 = rd.Next() % nBmpWidth;
int y1 = rd.Next() % nBmpHeight;
int x2 = rd.Next() % nBmpWidth;
int y2 = rd.Next() % nBmpHeight;
グラフ.DrawLine(ペン,x1,y1,x2,y2);
}
// 使用する文字セットはいつでも拡張でき、文字の出現確率も制御可能
string strCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 4. 文字を取得して描画するループ
文字列 strResult = "";
for(int i=0;i<nLen;i++)
{
int x = (i*13 + rd.Next(3));
int y = rd.Next(4) + 1;
// フォントを決定します。
System.Drawing.Font font = new System.Drawing.Font("Courier New",
12 + rd.Next()%4、
System.Drawing.FontStyle.Bold);
char c = strCode[rd.Next(strCode.Length)]; // ランダムな文字を取得します。
strResult += c.ToString();
// 文字を描画します
グラフ.DrawString(c.ToString(),
フォント、
new SolidBrush(System.Drawing.Color.FromArgb(nRed-60+y*3,nGreen-60+y*3,nBlue-40+y*3)),
×、
y);
}
// 5. バイトストリームを出力する
System.IO.MemoryStream bstream = 新しい System.IO.MemoryStream();
bmp.Save(bstream,System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Dispose();
グラフ.Dispose()
;
byte[] byteReturn = bstream.ToArray();
bstream.Close();
戻りバイトReturn;
2.
WebMethod をテストし、WebForm を追加し、上記の WebService を参照します。参照名は imagevr です。 Page_Load にコードを追加します:
...
画像vr.MyService imgsvr = 新しい画像vr.MyService();
文字列 strKey = "";
byte[] データ = imgsvr.GenerateVerifyImage(5,ref strKey);
Response.OutputStream.Write(data,0,data.Length);
...
3. 走ります。 Web フォームが更新されるたびに、新しく生成された画像検証コードが表示され、関数の出力パラメーター strKey によって検証コードの実際の内容が保存され、検証のためにセッションに保存できます。
前回画像認証コードを開発した後、友人たちの提案に基づいて、認証コードは(人にとって)認識しやすく、解読されにくく、美しいという原則に基づいて、認証コード生成アルゴリズムが改良されました。画像フィルタ法を使用して画像をフィルタリングしました。検証コードにはクラック防止干渉が適用され、結果の画像の例は次のとおりです。
フィルターエフェクトは主にウェーブアルゴリズムを使用しており、X軸とY軸のサイン波形を処理して重ね合わせ効果を生み出します。アルゴリズムの主な説明は次のとおりです。
private const double PI = 3.1415926535897932384626433832795;
private const double PI2 = 6.283185307179586476925286766559;
/// <概要>
/// 正弦波の歪んだ画像
/// </概要>
/// <param name="srcBmp"></param>
/// <param name="bXDir"></param>
/// <param name="nMultValue">波形の振幅倍数</param>
/// <param name="dPhase">波形の開始位相、値の範囲 [0-2*PI)</param>
/// <戻り値></戻り値>
public System.Drawing.Bitmap TwistImage(Bitmap srcBmp,bool bXDir,double dMultValue,double dPhase)
{
System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width,srcBmp.Height);
// ビットマップの背景を白で塗りつぶします。
System.Drawing.Graphics グラフ = System.Drawing.Graphics.FromImage(destBmp);
graph.FillRectangle(new SolidBrush(System.Drawing.Color.White),0,0,destBmp.Width,destBmp.Height);
グラフ.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++)
{
ダブル dx = 0;
dx = bXDir ? (PI2*(double)j)/dBaseAxisLen : (PI2*(double)i)/dBaseAxisLen;
dx += dフェーズ;
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);
}
}
destBmp を返します
。
、
2 つの波形エフェクトを重ね合わせたもので、それぞれ X 軸方向と Y 軸方向のエフェクトです。エッジの背景色の塗りつぶしをキャンセルすると、その効果がわかります。以下に示すように、グラフィック上のアルゴリズム:
この方法で生成された確認コードは、Google サイトの確認コードとよく似ています。もちろん、興味があれば、ストレッチ、回転、モザイクなどの他のフィルター効果を追加することもできます。ただし、Web サイトの検証コードが複雑であればあるほど、速度とセキュリティのバランスを見つける必要があることに注意してください。