期望效果如下:给每张图片的右下角添加一个文字水印。
1.准备画布
使用Bitmap加载图片,并创建画布。
var img = Bitmap.FromFile("1.png"); var g = Graphics.FromImage(img); //设置画布平滑性 g.SmoothingMode = SmoothingMode.AntiAlias;
如果不设置g.SmoothingMode,则绘制三角形时,斜边会出现锯齿。具体可参考:https://msdn.microsoft.com/zh-cn/library/z714w2y9.aspx
2.填充半透明三角形
首先确定三角边的长度,此处使用等边直角三角形,因此取图片长和宽中较小的一边的三分之一作为直角边。
然后开始添加三角形的形状,使用GraphicsPath记录连续的直线,位置是从三角形的左下角-->右上角-->右下角直角-->左下角。
最后填充三角形形状,Color.FromArgb(120, Color.Black)可实现半透明效果,120的值在0-255之间,255为不透明。
//填充半透明三角形 var triggleLeg = (img.Width > img.Height ? img.Height : img.Width) / 3; var path = new GraphicsPath(); path.AddLine(img.Width - triggleLeg, img.Height, img.Width, img.Height - triggleLeg); path.AddLine(img.Width, img.Height - triggleLeg, img.Width, img.Height); path.AddLine(img.Width, img.Height, img.Width - triggleLeg, img.Height); g.FillPath(new SolidBrush(Color.FromArgb(120, Color.Black)), path);
3.旋转画布
首先将画布的坐标原点移动到三角形斜边的中心,这样接下来绘制文字时方便控制文字位置。然后将画布旋转45度。
//将原点移动到三角形斜边的中间位置 g.TranslateTransform(img.Width - triggleLeg / 2, img.Height - triggleLeg / 2); //旋转45度 g.RotateTransform(-45);
如果不是等边直角三角形,则g.RotateTransform(-45)中的度数需要计算。根据公式 a2+b2=c2,可计算出斜边长度,然后根据 角度θ=arccos(a/c)可计算出角度。
//Math.Acos返回值是相对PI的值,因此需要转换为度数 var angle = Math.Acos(a / Math.Sqrt(Math.Pow(a, 2) + Math.Pow(b, 2))) / Math.PI * 180; g.RotateTransform((float)-angle);
4.绘制文字
绘制文字时,为保证文字居中,需要首先测量文字的大小。如果文字较多,长度超过了最大显示区域,则需要再对文字进行换行处理,这里暂时没有做。
绘制文字的起点为:0-长度/2,这样能保证文字居中显示。
//绘制水印文字 var font = new Font("Microsoft Yahei", 10, FontStyle.Regular); string text = "龙云是也"; //测量文字长度 var size = g.MeasureString(text, font); //绘制文字时,以文字长度的中间位置为中心,因此绘制的起点为:0-长度/2;并设置高度距离原点半行高 g.DrawString(text, font, Brushes.White, -size.Width / 2, size.Height / 2); size = g.MeasureString(DateTime.Now.ToString("yyyy-MM-dd"), font); g.DrawString(DateTime.Now.ToString("yyyy-MM-dd"), font, Brushes.White, -size.Width / 2, size.Height * 3 / 2);
最终效果如下: