主要用到System.Drawing 命名空间下的相关类,如Brush、Image、Bitmap、Graphics等等类
Image类可以从图片文件创建Image的实例,Bitmap可以从文件也可以从已有的Image对象创建实例,而Graphics类则是封装了对图像的相关操作,可以理解为一个绘图的面板,在这个面板里你可以添加文字,添加背景等等很多常规绘图软件具备的功能。
下面就怎样添加水印做简单的介绍:
在图片上写字
为了方便理解我把水印分为文字型的水印以及图片型的水印,它们都派生自WatermarkPainter基类,需要实现基类中的AddWatermark的方法,这个方法是用来具体的绘图用。
WatermarkPainter类如下:
using System.Drawing; using System.IO; using System.Text; using System; namespace Juice.Common.Drawing { /// <summary> /// 图片水印绘制器 /// </summary> public abstract class WatermarkPainter : IDisposable { /// <summary> /// 构造函数 /// </summary> /// <param name="rawImagePath"></param> /// <param name="alpha"></param> /// <param name="replaceRawImage"></param> protected WatermarkPainter(string rawImagePath, int alpha, bool replaceRawImage) { ImageToBePainted = rawImagePath; WatermarkAlpha = alpha; ReplaceRawImage = replaceRawImage; } /// <summary> /// 构造函数 /// </summary> /// <param name="rawImagePath"></param> /// <param name="alpha"></param> protected WatermarkPainter(string rawImagePath, int alpha) : this(rawImagePath, alpha, true) { } /// <summary> /// 为临时存储文件添加的后缀 /// </summary> private string m_TempFileSuffix = ".juice.watermark.temp"; /// <summary> /// 水印的透明度 /// </summary> private int m_WatermarkAlpha; /// <summary> /// 水印透明度 /// </summary> public int WatermarkAlpha { get { ) m_WatermarkAlpha = ; ) m_WatermarkAlpha = ; return m_WatermarkAlpha; } set { m_WatermarkAlpha = value; } } private string m_ImageToBePainted; /// <summary> /// 添加水印的图片的物理路径 /// </summary> public string ImageToBePainted { get { return m_ImageToBePainted; } set { m_ImageToBePainted = value; } } private bool m_ReplaceRawImage; /// <summary> /// 是否用加了水印的图片替换原有的图片 /// </summary> public bool ReplaceRawImage { get { return m_ReplaceRawImage; } set { m_ReplaceRawImage = value; } } private string m_TempImagePath; /// <summary> /// 加了水印后的临时储存名称 /// </summary> protected string TempImagePath { get { if (string.IsNullOrEmpty(this.m_TempImagePath)) { StringBuilder s = new StringBuilder(ImageToBePainted); s.Append(this.m_TempFileSuffix); this.m_TempImagePath = s.ToString(); } return m_TempImagePath; } set { m_TempImagePath = value; } } /// <summary> /// 原始图像 /// </summary> private Image m_RawImage; /// <summary> /// 为图片添加水印 /// </summary> public void PaintWaterMark() { if (string.IsNullOrEmpty(ImageToBePainted)) return; if (!File.Exists(ImageToBePainted)) throw new FileNotFoundException(string.Format("file {0} not found.", ImageToBePainted)); bool succeed; if (m_RawImage == null) m_RawImage = Image.FromFile(ImageToBePainted); ///原始的图片 using (Bitmap newImage = new Bitmap(m_RawImage.Width, m_RawImage.Height)) { ///创建绘制图片的图面 using (Graphics g = Graphics.FromImage(newImage)) { g.DrawImage(m_RawImage, , , m_RawImage.Width, m_RawImage.Height); ///开始绘制水印 succeed = AddWatermark(g, newImage); } if (succeed) ///将图片保存到临时的文件 newImage.Save(TempImagePath); if (m_RawImage != null) m_RawImage.Dispose(); } if (succeed && ReplaceRawImage) { //删除原来的文件 if (File.Exists(ImageToBePainted)) File.Delete(ImageToBePainted); FileInfo info = new FileInfo(TempImagePath); if (info.Exists) { info.MoveTo(ImageToBePainted); } } } /// <summary> /// 添加水印,继承类可以用来添加自己的水印 /// </summary> /// <param name="graphics"></param> /// <param name="newImage"></param> /// <returns></returns> protected abstract bool AddWatermark(Graphics graphics, Bitmap newImage); #region IDisposable 成员 public virtual void Dispose() { } #endregion } }
文字型的水印的类是TextWatermarkPainter类
using System.Drawing; using System.IO; using System.Text; using System; namespace Juice.Common.Drawing { /// <summary> /// 添加文字水印 /// </summary> public sealed class TextWatermarkPainter : WatermarkPainter { /// <summary> /// 构造函数 /// </summary> /// <param name="rawImagePath"></param> /// <param name="alpha"></param> /// <param name="text"></param> public TextWatermarkPainter(string rawImagePath, int alpha, string text) : base(rawImagePath, alpha) { WatermarkText = text; } private Font m_Font; /// <summary> /// 水印文字的字体 /// </summary> public Font Font { get { if (null == m_Font) m_Font = , FontStyle.Bold, GraphicsUnit.Pixel); return m_Font; } set { m_Font = value; } } private Color m_FontColor; /// <summary> /// 字体颜色 /// </summary> public Color FontColor { get { if (m_FontColor == null) m_FontColor = Color.DarkSeaGreen; return m_FontColor; } set { m_FontColor = value; } } private string m_WatermarkText; /// <summary> /// 水印的文字 /// </summary> public string WatermarkText { get { return m_WatermarkText; } set { m_WatermarkText = value; } } /// <summary> /// 实现添加水印的方法 /// </summary> /// <param name="graphics"></param> /// <param name="newImage"></param> /// <returns></returns> protected override bool AddWatermark(Graphics graphics, Bitmap newImage) { if (string.IsNullOrEmpty(WatermarkText)) return true; using (SolidBrush brush = new SolidBrush(Color.FromArgb(WatermarkAlpha, FontColor.R, FontColor.G, FontColor.B))) { Font font; ///添加文字位置 PointF f = new PointF(); float totalWidth = Font.Size * WatermarkText.Length; f.X = newImage.Width - totalWidth - ; f.Y = newImage.Height - Font.Height; ) { ///自动调整字体的大小 float width = newImage.Width / WatermarkText.Length; font = new Font(Font.FontFamily, width, GraphicsUnit.Pixel); } else font = Font; graphics.DrawString(WatermarkText, font, brush, f); } return true; } #region IDisposable 成员 public override void Dispose() { Font.Dispose(); base.Dispose(); } #endregion } }
下面是对文字型水印的测试:
default.aspx内容如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> 水印文字:<asp:TextBox ID="watermarkTextBox" runat="server"></asp:TextBox><br /> 选择上传图片:<asp:FileUpload ID="FileUpload1" runat="server" Width="189px" /> <br /> <asp:Button ID="uploadFileBtn" runat="server" Text="上传图片并且加文字水印" onclick="uploadFileBtn_Click" /> <br />加了水印的图像如下: <asp:Image ID="image" runat="server" /> </div> </form> </body> </html>
default.aspx.cs代码如下:
using System; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using Juice.Common.Drawing; using System.Web.Hosting; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void uploadFileBtn_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(this.watermarkTextBox.Text)) return; if (FileUpload1.HasFile) { string contentType = FileUpload1.PostedFile.ContentType; if (contentType.StartsWith("image/")) { string filePath = Server.MapPath(string.Format("~/{0}", FileUpload1.FileName)); ///保存文件 FileUpload1.SaveAs(filePath); ///加水印 this.AddWatermark(filePath, this.watermarkTextBox.Text); image.ImageUrl = string.Format("~/{0}", FileUpload1.PostedFile.FileName); } } } /// <summary> /// 添加水印 /// </summary> /// <param name="filePath"></param> /// <param name="watermaterText"></param> private void AddWatermark(string filePath, string watermaterText) { , watermaterText)) { painter.FontColor = System.Drawing.Color.DarkGreen; painter.PaintWaterMark(); } } }
摘自:http://hi.baidu.com/bopdawpdarbenxq/item/419b367ee84445285d17895d
ps:如果想用的话,完全可以简写,就两个方法。但面向对象开发,有一特性就是:增加代码的复用。这段代码中保存图片时,应用了临时文件做中转,方法比较好。临时文件里保存着加水印图片的数据,删除原文件后,把临时文件里的数据保存到被删除图片的路径下,这样加了水印的图片就会替换没有加了水印的图片,这时程序运行完后,临时文件会被删除。当构造函数ReplaceRawImage改成false时,会发现临时文件没有被删除。
在图片上画公司的标识
ImageWatermarkPainter类
前台:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> 水印文字:<asp:TextBox ID="watermarkTextBox" runat="server"></asp:TextBox><br /> 选择上传图片:<asp:FileUpload ID="FileUpload1" runat="server" Width="189px" /> <br /> <asp:Button ID="uploadFileBtn" runat="server" Text="上传图片并且加文字水印" onclick="uploadFileBtn_Click" /> <asp:Button ID="uploadAndAddImageBtn" runat="server" Text="上传图片并且添加半透明的图片水印" onclick="uploadAndAddImageBtn_Click" /> <br />加了水印的图像如下: <asp:Image ID="image" runat="server" /> </div> </form> </body> </html>
页面后台代码
public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void uploadFileBtn_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(this.watermarkTextBox.Text)) return; if (FileUpload1.HasFile) { string contentType = FileUpload1.PostedFile.ContentType; if (contentType.StartsWith("image/")) { string filePath = Server.MapPath(string.Format("~/{0}", Server.HtmlEncode(FileUpload1.PostedFile.FileName))); ///保存文件 FileUpload1.SaveAs(filePath); ///加水印 this.AddWatermark(filePath, this.watermarkTextBox.Text); image.ImageUrl = string.Format("~/{0}", Server.HtmlEncode(FileUpload1.PostedFile.FileName)); } } } /// <summary> /// 添加水印 /// </summary> /// <param name="filePath"></param> /// <param name="watermaterText"></param> private void AddWatermark(string filePath, string watermaterText) { , watermaterText)) { painter.FontColor = System.Drawing.Color.DarkGreen; painter.PaintWaterMark(); } } protected void uploadAndAddImageBtn_Click(object sender, EventArgs e) { if (FileUpload1.HasFile) { string contentType = FileUpload1.PostedFile.ContentType; if (contentType.StartsWith("image/")) { string filePath = Server.MapPath(string.Format("~/{0}", Server.HtmlEncode(FileUpload1.PostedFile.FileName))); ///保存文件 FileUpload1.SaveAs(filePath); ///加水印 this.AddImageWatermark(filePath); image.ImageUrl = string.Format("~/{0}", Server.HtmlEncode(FileUpload1.PostedFile.FileName)); } } } /// <summary> /// 添加图片水印 /// </summary> /// <param name="filePath"></param> private void AddImageWatermark(string filePath) { , Server.MapPath("~/watermark.gif"))) { painter.PaintWaterMark(); } } }
View Cod
ps:在WatermarkPainter painter = new ImageWatermarkPainter(filePath, 180, Server.MapPath("~/watermark.gif")))处可以修改gif图片。
当然此方也可以用来合并两张图片。摘自:http://hi.baidu.com/bopdawpdarbenxq/item/d42103b3568f22a4ebba9341