先看效果:
关键代码:
private void DrawWords(Graphics graphics, int width, int height, string phrase)
{
graphics.FillRectangle(Brushes.White, 0, 0, width, height);
using (var gp = new GraphicsPath())
{
gp.AddString(phrase,new FontFamily("Arial"), (int)FontStyle.Bold, 48f, new Point(0, 0), StringFormat.GenericDefault);
using (var gpp =
GraphicsPathDeform(gp, width, height))
{
var bounds = gpp.GetBounds();
var matrix = new Matrix();
var x = (width - bounds.Width) / 2 - bounds.Left;
var y = (height - bounds.Height) / 2 - bounds.Top;
matrix.Translate(x, y);
gpp.Transform(matrix);
graphics.FillPath(Brushes.Black, gpp);
}
}
graphics.Flush();
}
private GraphicsPath
GraphicsPathDeform(GraphicsPath path, int width, int height)
{
var WarpFactor = 3;
var xAmp = WarpFactor * width / 100d;
var yAmp = WarpFactor * height / 50d;
var xFreq = 2d * Math.PI / width;
var yFreq = 2d * Math.PI / height;
Random rng = new Random();
var deformed = new PointF[path.PathPoints.Length];
var xSeed = rng.NextDouble() * 2 * Math.PI;
var ySeed = rng.NextDouble() * 2 * Math.PI;
var i = 0;
foreach (var original in path.PathPoints)
{
var val = xFreq * original.X + yFreq * original.Y;
var xOffset = (int)(xAmp * Math.Sin(val + xSeed));
var yOffset = (int)(yAmp * Math.Sin(val + ySeed));
deformed[i++] = new PointF(original.X + xOffset,original.Y + yOffset);
}
return new GraphicsPath(deformed, path.PathTypes);
}
测试:
private void button2_Click(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(600, 600);
Graphics g = Graphics.FromImage(bmp);
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
DrawWords(g, 500, 100, "Guangdong, China");
pictureBox1.Image = bmp;
g.Dispose();
}
当然,如果你认为上面的还不够验证要求,还可以加上背景杂色、背景图片或者不规则的线条、曲线等,也可以先将上面的文字进行旋转等变形后,再做上述处理,但有一个大原则:要方便人眼识别,而程序无法识别或很难识别。这里就不再详述。