문제

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!

도움이 되었습니까?

해결책

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;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top