Pregunta

I found these codes in SO and MSDN for creating CAPTCHA image:

private Image DrawText(String text, Font font, Color textColor, Color backColor)
    {
        //first, create a dummy bitmap just to get a graphics object
        Image img = new Bitmap(1, 1);
        Graphics drawing = Graphics.FromImage(img);

        //measure the string to see how big the image needs to be
        SizeF textSize = drawing.MeasureString(text, font);

        //free up the dummy image and old graphics object
        img.Dispose();
        drawing.Dispose();

        //create a new image of the right size
        Bitmap b = new Bitmap((int)textSize.Width, (int)textSize.Height);
        int distortion = 2;
        Bitmap copy = b;
        for (int y = 0; y < textSize.Height; y++)
        {
            for (int x = 0; x < textSize.Width; x++)
            {
                int newX = (int)(x + (distortion * Math.Sin(Math.PI * y / 64.0)));
                int newY = (int)(y + (distortion * Math.Cos(Math.PI * x / 64.0)));
                if (newX < 0 || newX >= textSize.Width) newX = 0;
                if (newY < 0 || newY >= textSize.Height) newY = 0;
                b.SetPixel(x, y, copy.GetPixel(newX, newY));
            }
        }
        img = b;
        drawing = Graphics.FromImage(img);

        //paint the background
        drawing.Clear(backColor);

        //create a brush for the text
        Brush textBrush = new SolidBrush(textColor);

        drawing.DrawString(text, font, textBrush, 0, 0);

        drawing.Save();

        textBrush.Dispose();
        drawing.Dispose();

        return img;

    }

I also use this code to output image to browser :

 Image image = DrawText("3", new Font("Thahoma", 20), Color.Black, Color.White);
 context.Response.ContentType = "image/png";
 using (MemoryStream ms = new MemoryStream())
  {
       image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
       ms.WriteTo(context.Response.OutputStream);
  }

but this code not output image without any error;when I clear those fors it show image. my web application will run in private intranet,so don't recommend reCAPTCHA!

¿Fue útil?

Solución

The original DrawImage function can't produce the correct bitmap because it is buggy (e.g. it fails to me with ArgumentOutOfRangeException). Try the corrected version:

Image DrawText(string text, Font font, Color textColor, Color backColor) {
    Size textSize;
    using(Image tmp = new Bitmap(1, 1)) {
        using(Graphics g = Graphics.FromImage(tmp)) {
            textSize = Size.Ceiling(g.MeasureString(text, font));
        }
    }
    Bitmap bitmap = new Bitmap(textSize.Width, textSize.Height);
    using(Graphics g = Graphics.FromImage(bitmap)) {
        g.Clear(backColor);
        using(Brush textBrush = new SolidBrush(textColor)) {
            g.DrawString(text, font, textBrush, 0, 0);
        }
    }
    const double Distortion = 2.0;
    const double F = Math.PI / 64.0;
    using(Bitmap copy = bitmap.Clone() as Bitmap) {
        for(int y = 0; y < textSize.Height; y++) {
            for(int x = 0; x < textSize.Width; x++) {
                int newX = (int)(x + Distortion * Math.Sin(F * y));
                int newY = (int)(y + Distortion * Math.Cos(F * x));
                if(newX < 0 || newX >= textSize.Width) newX = 0;
                if(newY < 0 || newY >= textSize.Height) newY = 0;
                bitmap.SetPixel(x, y, copy.GetPixel(newX, newY));
            }
        }
    }
    return bitmap;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top