期望效果如下:给每张图片的右下角添加一个文字水印。
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);
//绘制的起点为:0-长度/2;并设置高度距离原点1行半高
g.DrawString(DateTime.Now.ToString("yyyy-MM-dd"), font, Brushes.White, -size.Width / 2, size.Height * 3 / 2);
最终效果如下:
protected void btnWonderful_Click(object sender, EventArgs e)
{
//绘制画布:图片即画布
System.Drawing.Image img = System.Drawing.Image.FromStream(
ImgHelper.GetPicture("http://s16.sinaimg.cn/mw690/001lHJMSgy6VzGwi8N16f&690"));
using (Graphics g = Graphics.FromImage(img))
{
//设置画布平滑性
g.SmoothingMode = SmoothingMode.AntiAlias;
//填充半透明三角形
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);
//将原点移动到三角形斜边的中间位置
g.TranslateTransform(img.Width - triggleLeg / 2, img.Height - triggleLeg / 2);
//旋转45度
g.RotateTransform(-45);
//绘制水印文字
var font = new Font("Microsoft Yahei", 15, 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);
}
//设置水印后的图片的相对路径和名字
string imgpath = "images/" + DateTime.Now.ToString("yyyy年MM月dd日hh时mm分ss秒") +
Path.GetFileName("https://i0.hdslb.com/bfs/article/qqqqq.jpg");
img.Save(Server.MapPath(imgpath));
}