Esempio n. 1
0
        public Captcha()
        {
            CleanUp();

            var rnd        = new Random();
            int randNumber = rnd.Next((int)Math.Pow(10, Digits));

            using var img = new Image <Rgba32>(Width, Height);
            var font = new FontCollection()
                       .Install(System.IO.Path.Combine(RootPath, FontPath))
                       .CreateFont(30, FontStyle.Regular);

            string txt           = randNumber.ToString("D" + Digits);
            var    renderOptions = new RendererOptions(font);

            var charSize = new FontRectangle[txt.Length];

            for (int i = 0; i < charSize.Length; i++)
            {
                charSize[i] = TextMeasurer.Measure(txt.Substring(i, 1), renderOptions);
            }

            float x = ((float)rnd.NextDouble() + 1f) * Width * 0.1f, y;
            float spaceSum = Width - 2 * x - charSize.Sum(s => s.Width);
            float space;

            img.Mutate(ctx =>
            {
                ctx.Fill(BackColor);

                for (int i = 0; i < txt.Length; i++)
                {
                    y = (float)rnd.NextDouble() * (Height - charSize[i].Height);

                    ctx.Fill(ForeColor,
                             TextBuilder.GenerateGlyphs(txt.Substring(i, 1), renderOptions)
                             .Rotate((float)rnd.NextDouble() * .6f - .3f) //almost between -15 and 15
                             .Translate(x, y));

                    if (i + 1 < txt.Length)
                    {
                        space     = (float)rnd.NextDouble() * spaceSum / (Digits - i - 1f);
                        spaceSum -= space;
                        x        += charSize[i].Width + space;
                    }
                }

                for (int i = 0; i < 5; i++)
                {
                    ctx.DrawBeziers(ForeColor, Math.Min(Width, Height) / Digits / 7f,
                                    new PointF((float)rnd.NextDouble() * Width * 0.2f, Height / 4f * (1f + 2f * (float)rnd.NextDouble())),
                                    new PointF(Width / 3f, (float)rnd.NextDouble() * Height),
                                    new PointF(Width / 3f * 2f, (float)rnd.NextDouble() * Height),
                                    new PointF(Width * (1f - (float)rnd.NextDouble() * 0.2f), Height / 4f * (1f + 2f * (float)rnd.NextDouble())));
                }
            });

            Code = BitConverter.ToInt64(Guid.NewGuid().ToByteArray(), 4);

            using (var cnnct = new SqlConnection(ConnectionString))
            {
                using var cmnd = new SqlCommand($@"insert into dbo.CaptchaCodes (Id, Captcha, CreationDate) 
                    values (@id, @captcha, @date)", cnnct);
                cmnd.Parameters.Add(new SqlParameter("@id", Code));
                cmnd.Parameters.Add(new SqlParameter("@captcha", randNumber));
                cmnd.Parameters.Add(new SqlParameter("@date", DateTime.Now));
                cnnct.Open();
                cmnd.ExecuteNonQuery();
            }

            var encoder = new PngEncoder {
                ColorType = PngColorType.Palette
            };

            using var mem = new MemoryStream();
            img.SaveAsPng(mem, encoder);
            Src = "data:image/png;base64," + Convert.ToBase64String(mem.ToArray());
        }