【C#】三维立体验证码 (3DCaptcha) (转)

引用地址:http://www.cnblogs.com/Aimeast/archive/2011/05/02/2034525.html

 

本技术来源:


3DCaptcha http://www-personal.umich.edu/~mressl/3dcaptcha/


下载地址 http://code.google.com/p/3dcaptcha/


官方LOGO


image



本例完全由此样例程序翻译而来,未作任何附加处理.


以下是C#对此算法的实现










001/*






002 *
3DCaptcha for .net






003






004 * http://www-personal.umich.edu/~mressl/3dcaptcha/    
(php)







006






007 *
Translate :  Aimeast






008 *
Blog      :  http://www.cnblogs.com/Aimeast/






009 */






010






011using System;






012using System.Drawing;






013






014namespace Captcha






015{






016    public static
class Captcha






017    {






018        private static
double[]
addVector(
double[] a, double[] b)






019        {






020            return new
double[] { a[0] +
b[0], a[1] + b[1], a[2] + b[2] };






021        }






022






023        private static
double[]
scalarProduct(
double[] vector, double scalar)






024        {






025            return new
double[] {
vector[0] * scalar, vector[1] * scalar, vector[2] * scalar };






026        }






027






028        private static
double dotProduct(double[] a,
double[]
b)






029        {






030            return a[0] * b[0] +
a[1] * b[1] + a[2] * b[2];






031        }






032






033        private static
double norm(double[] vector)






034        {






035            return Math.Sqrt(dotProduct(vector, vector));






036        }






037






038        private static
double[]
normalize(
double[] vector)






039        {






040            return scalarProduct(vector, 1.0 / norm(vector));






041        }






042







044        private static
double[]
crossProduct(
double[] a, double[] b)






045        {






046            return new
double[] {






047                (a[1] * b[2] - a[2] * b[1]),






048                (a[2] * b[0] - a[0] * b[2]),






049                (a[0] * b[1] - a[1] * b[0])






050            };






051        }






052






053        private static
double[]
vectorProductIndexed(
double[] v, double[] m,
int i)






054        {






055            return new
double[]{






056                v[i + 0] * m[0] + v[i + 1] * m[4] + v[i + 2] * m[8] + v[i +
3] * m[12],






057                v[i + 0] * m[1] + v[i + 1] * m[5] + v[i + 2] * m[9] + v[i +
3] * m[13],






058                v[i + 0] * m[2] + v[i + 1] * m[6] + v[i + 2] * m[10]+ v[i +
3] * m[14],






059                v[i + 0] * m[3] + v[i + 1] * m[7] + v[i + 2] * m[11]+ v[i +
3] * m[15]






060            };






061        }






062






063        private static
double[]
vectorProduct(
double[] v, double[] m)






064        {






065            return vectorProductIndexed(v, m, 0);






066        }






067






068        private static
double[]
matrixProduct(
double[] a, double[] b)






069        {






070            double[] o1 =
vectorProductIndexed(a, b, 0);






071            double[] o2 =
vectorProductIndexed(a, b, 4);






072            double[] o3 =
vectorProductIndexed(a, b, 8);






073            double[] o4 =
vectorProductIndexed(a, b, 12);






074






075            return new
double[]{






076                o1[0], o1[1], o1[2], o1[3],






077                o2[0], o2[1], o2[2], o2[3],






078                o3[0], o3[1], o3[2], o3[3],






079                o4[0], o4[1], o4[2], o4[3]






080            };






081        }






082







084        private static
double[]
cameraTransform(
double[] C, double[] A)






085        {






086            double[] w =
normalize(addVector(C, scalarProduct(A, -1)));






087            double[] y =
new double[] { 0, 1, 0 };






088            double[] u =
normalize(crossProduct(y, w));






089            double[] v =
crossProduct(w, u);






090            double[] t =
scalarProduct(C, -1);






091






092            return new
double[]{






093                u[0], v[0], w[0], 0,






094                u[1], v[1], w[1], 0,






095                u[2], v[2], w[2], 0,






096                dotProduct(u, t), dotProduct(v, t), dotProduct(w, t), 1






097            };






098        }






099







101        private static
double[]
viewingTransform(
double fov, double
n, double
f)






102        {






103            fov *= (Math.PI / 180);






104            double cot = 1.0 /
Math.Tan(fov / 2);






105






106            return new
double[]{






107                cot,    0,      0,      0,






108                0,      cot,    0,      0, 






109                0,      0,      (f + n) / (f - n),      -1,






110                0,      0,      2 * f * n / (f - n),    0






111            };






112        }






113






114        public static
Image Generate(string captchaText)






115        {






116            Random rnd = new
Random();






117






118            // 3dcha parameters






119            int fontsize = 24;






120            Font font = new
Font("Arial", fontsize);






121






122            SizeF sizeF;






123            using (Graphics g =
Graphics.FromImage(
new Bitmap(1, 1)))






124            {






125                sizeF = g.MeasureString(captchaText, font, 0,
StringFormat.GenericDefault);






126            }






127






128            int image2d_x =
(
int)sizeF.Width;






129            int image2d_y =
(
int)(fontsize * 1.3);






130






131            double bevel = 4;






132






133            // Create 2d image






134            Bitmap image2d = new Bitmap(image2d_x,
image2d_y);






135            Color black = Color.Black;






136            Color white = Color.White;






137






138            // Paint 2d image






139            using (Graphics g =
Graphics.FromImage(image2d))






140            {






141                g.Clear(black);






142                g.DrawString(captchaText, font, Brushes.White, 0, 0);






143            }






144            // Calculate projection matrix






145            double[] T =
cameraTransform(






146                   new double[] {
rnd.Next(-90, 90), -200, rnd.Next(150, 250) },






147                   new double[] { 0, 0, 0 }






148                );






149            T = matrixProduct(






150                    T,






151                    viewingTransform(60, 300, 3000)






152                );






153






154            // Calculate coordinates






155            double[][] coord =
new double[image2d_x *
image2d_y][];






156






157            int count = 0;






158            for (int y = 0; y <
image2d_y; y += 2)






159            {






160                for (int x = 0; x <
image2d_x; x++)






161                {






162                    // calculate x1, y1, x2, y2






163                    int xc = x - image2d_x
/ 2;






164                    int zc = y - image2d_y
/ 2;






165                    double yc =
-(
double)(image2d.GetPixel(x, y).ToArgb() & 0xff) / 256 *
bevel;






166                    double[] xyz =
new double[] { xc, yc, zc,
1 };






167                    xyz = vectorProduct(xyz, T);






168






169                    coord[count] = xyz;






170                    count++;






171                }






172            }






173






174            // Create 3d image






175            int image3d_x = 256;






176            //$image3d_y = $image3d_x / 1.618;






177            int image3d_y =
image3d_x * 9 / 16;






178            Bitmap image3d = new Bitmap(image3d_x,
image3d_y);






179            Color fgcolor = Color.White;






180            Color bgcolor = Color.Black;






181            using (Graphics g =
Graphics.FromImage(image3d))






182            {






183                g.Clear(bgcolor);






184                count = 0;






185                double scale = 1.75 -
(
double)image2d_x / 400;






186                for (int y = 0; y <
image2d_y; y += 2)






187                {






188                    for (int x = 0; x <
image2d_x; x++)






189                    {






190                        if (x > 0)






191                        {






192                            double x0 = coord[count
- 1][0] * scale + image3d_x / 2;






193                            double y0 = coord[count
- 1][1] * scale + image3d_y / 2;






194                            double x1 =
coord[count][0] * scale + image3d_x / 2;






195                            double y1 =
coord[count][1] * scale + image3d_y / 2;






196                            g.DrawLine(new
Pen(fgcolor), (float)x0, (float)y0, (float)x1, (float)y1);






197                        }






198                        count++;






199                    }






200                }






201            }






202            return image3d;






203        }






204    }






205}

使用方法










1this.BackgroundImage = Captcha.Generate("Code");

效果截图


image

posted @ 2011-09-07 11:50  冰封的心  阅读(268)  评论(0)    收藏  举报