0

CAPTCHA イメージを作成するための SO および MSDN でこれらのコードを見つけました。

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;

    }

また、このコードを使用して画像をブラウザに出力します。

 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);
  }

しかし、このコードはエラーなしで画像を出力しません。それらをクリアするforと、画像が表示されます。私の Web アプリケーションはプライベート イントラネットで実行されるため、reCAPTCHA はお勧めしません。

4

1 に答える 1

2

元のDrawImage関数はバグがあるため、正しいビットマップを生成できません (たとえば、ArgumentOutOfRangeException で失敗します)。修正版を試してください:

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;
}
于 2013-08-21T04:46:51.433 に答える