我在SO和MSDN中发现这些代码用于创建CAPTCHA图像:
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
时它显示图像。 我的网络应用程序将在私有内部网运行,因此不建议使用reCAPTCHA!
答案 0 :(得分: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;
}