ASP.NET 图片加水印,水印位置自定义
VS目录:

代码如下:
Default.aspx 页面
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ImageWaterMark._Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><head runat="server"> <title></title> <style type="text/css"> .imgFload { float:left; } </style></head><body> <form id="form1" runat="server"> <div> 请选择图片:<asp:FileUpload ID="fuImage" runat="server" /><br /> 请输入水印图片的位置:<asp:DropDownList ID="ddlWaterImgPosition" runat="server" AppendDataBoundItems="true" DataTextField="EnumDisplayText" DataValueField="EnumValue"> </asp:DropDownList><br /> <asp:Button ID="btnSubmit" runat="server" Text="提交" OnClick="btnSubmit_Click" /> <asp:Button ID="btnRecut" runat="server" Text="重新裁剪" OnClick="btnRecut_Click" Visible="false"/> </div> <div style="float:left;"> <asp:Image ID="imgResult" runat="server" Visible="false" CssClass="imgFload" /> <asp:PlaceHolder ID="phImgContainer" runat="server"></asp:PlaceHolder> </div> </form></body></html> |
Default.aspx.cs 代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.IO;namespace ImageWaterMark{ public partial class _Default : System.Web.UI.Page { /// <summary> /// 图像集合 /// </summary> public List<string> ImgFilePathList { get { return ViewState["ImgFilePathList"] == null ? new List<string>() : (List<string>)ViewState["ImgFilePathList"]; } set { ViewState["ImgFilePathList"] = value; } } /// <summary> /// 加载事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Page_Load(object sender, EventArgs e) { if(!IsPostBack) { this.ddlWaterImgPosition.DataSource = EnumDescription.GetFieldTexts(typeof(ImagePosition)); this.ddlWaterImgPosition.DataBind(); } } /// <summary> /// 提交 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnSubmit_Click(object sender, EventArgs e) { ImagePosition imagePosition = (ImagePosition)Convert.ToInt32(this.ddlWaterImgPosition.SelectedValue); string dateTimeStr = DateTime.Now.ToString("yyyyMMddHHmmssmmm"); string saveVirualPath = "~/images/" + dateTimeStr; string errorMessage; bool flag = CommonClass.ValidateImgExtensionAndSave(this.fuImage, ref saveVirualPath, out errorMessage, false, true, 1); if(!flag) { this.ClientScript.RegisterStartupScript(btnSubmit.GetType(), "", "alert('" + errorMessage + "')", true); return; } string newSavedVirualPath = "~/modifiedImages/" + dateTimeStr + ".jpg"; string newSavedPhysicalPath = Server.MapPath(newSavedVirualPath); flag = CoverWaterImage.MakeCoverWaterImage(Server.MapPath(saveVirualPath), newSavedPhysicalPath, out errorMessage, imagePosition); if(!flag) { this.ClientScript.RegisterStartupScript(btnSubmit.GetType(), "", "alert('" + errorMessage + "')", true); return; } this.imgResult.Visible = true; this.btnRecut.Visible = true; this.imgResult.ImageUrl = newSavedVirualPath; } /// <summary> /// 重新裁剪 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void btnRecut_Click(object sender, EventArgs e) { ImagePosition imagePosition = (ImagePosition)Convert.ToInt32(this.ddlWaterImgPosition.SelectedValue); string savedVirualPath = this.imgResult.ImageUrl; string fileName = Path.GetFileName(savedVirualPath); string newSavedVirualPath = "~/modifiedImages/" + DateTime.Now.ToString("yyyyMMddHHmmssmmm") + ".jpg"; string newSavedPhysicalPath = Server.MapPath(newSavedVirualPath); string errorMessage; bool flag = CoverWaterImage.MakeCoverWaterImage(Server.MapPath("~/images/" + fileName), newSavedPhysicalPath, out errorMessage, imagePosition); if (!flag) { this.ClientScript.RegisterStartupScript(btnSubmit.GetType(), "", "alert('" + errorMessage + "')", true); return; } List<string> imgList = ImgFilePathList; imgList.Add(newSavedVirualPath); foreach (string item in imgList) { Image imgNew = new Image(); imgNew.ImageUrl = item; this.phImgContainer.Controls.Add(imgNew); } ImgFilePathList = imgList; } }} |
CommonClass.cs 代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI.WebControls;using System.IO;using System.Drawing;namespace ImageWaterMark{ public class CommonClass { /// <summary> /// 验证图片的真实类型,并尝试保存图片 /// </summary> /// <param name="hifile">FileUpload 控件ID</param> /// <param name="savedVirtualPath">要保存图片的虚拟路径(虚拟路径不能包括扩展名,正确的写法比如"/video/2010/5/中国人"),如果上传失败,则保存的路径为空</param> /// <param name="errorMessage">如果上传失败,错误消息</param> /// <param name="allowFileEmpty">是否允许FileUpload没有文件,如果允许,则当FileUpload为空时,不显示错误信息</param> /// <param name="limitImgSize">是否限制图片的大小,true表示限制</param> /// <param name="imgSize_MB">如果限制图片的大小成立,即参数“limitImgSize”的值为True,则最大能允许的图片的兆数(MB)</param> /// <returns>验证结果,true表示成功,false表示失败</returns> public static bool ValidateImgExtensionAndSave(FileUpload hifile, ref string savedVirtualPath, out string errorMessage, bool allowFileEmpty, bool limitImgSize, double imgSize_MB) { if (hifile != null && hifile.HasFile) { Stream streamInput = hifile.PostedFile.InputStream; BinaryReader r = new BinaryReader(streamInput); string fileclass = ""; byte buffer; try { buffer = r.ReadByte(); fileclass = buffer.ToString(); buffer = r.ReadByte(); fileclass += buffer.ToString(); //r.Close(); } catch (Exception) { r.Close(); streamInput.Close(); errorMessage = "读取文件流失败,请确定您文件的正确性!"; savedVirtualPath = string.Empty; return false; } //说明255216是jpg;7173是gif;6677是BMP,13780是PNG;7790是exe,8297是rar if (fileclass == "255216" || fileclass == "7173" || fileclass == "6677" || fileclass == "13780") { //成功 if (limitImgSize) { //限制图片的大小 double imgSize = (double)streamInput.Length / (1024 * 1024); if (imgSize > imgSize_MB) { errorMessage = "图片的大小最大不能超过" + imgSize_MB + "M"; savedVirtualPath = string.Empty; streamInput.Close(); return false; } } string imgExtension = string.Empty; System.Drawing.Imaging.ImageFormat imgFormat; switch (fileclass) { case "255216": imgExtension = ".jpg"; imgFormat = System.Drawing.Imaging.ImageFormat.Jpeg; break; case "7173": imgExtension = ".gif"; imgFormat = System.Drawing.Imaging.ImageFormat.Gif; break; case "6677": imgExtension = ".bmp"; imgFormat = System.Drawing.Imaging.ImageFormat.Bmp; break; case "13780": imgExtension = ".png"; imgFormat = System.Drawing.Imaging.ImageFormat.Png; break; default: imgFormat = System.Drawing.Imaging.ImageFormat.Jpeg; break; } System.Drawing.Image img = System.Drawing.Image.FromStream(streamInput); if (savedVirtualPath.LastIndexOf('/') == (savedVirtualPath.Length - 1)) { throw new Exception("没有文件名,正确的格式应该比如为:/目录名/.../myImg,其中\"myImg\"表示文件名!"); } savedVirtualPath = savedVirtualPath + imgExtension; string physicalImgPath = HttpContext.Current.Server.MapPath(savedVirtualPath); string physicalImgDictionaryPath = physicalImgPath.Substring(0, physicalImgPath.LastIndexOf('\\')); if (!Directory.Exists(physicalImgDictionaryPath)) { Directory.CreateDirectory(physicalImgDictionaryPath); } img.Save(HttpContext.Current.Server.MapPath(savedVirtualPath), imgFormat); img.Dispose(); streamInput.Close(); errorMessage = string.Empty; return true; } else { errorMessage = "图片格式不正确!"; savedVirtualPath = string.Empty; return false; } } else { savedVirtualPath = string.Empty; if (allowFileEmpty) { //允许上传的文件为空 errorMessage = string.Empty; return true; } else { //一定要有文件 errorMessage = "没有文件,或文件为空!"; return false; } } } }} |
ImagePosition.cs 代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.ComponentModel;namespace ImageWaterMark{ public enum ImagePosition { /// <summary> /// 默认 /// </summary> [EnumDescription("默认",1)] Default = 0, /// <summary> /// 左上方 /// </summary> [EnumDescription("左上方")] LeftTop = 1, /// <summary> /// 正上方 /// </summary> [EnumDescription("正上方")] Top = 2, /// <summary> /// 右上方 /// </summary> [EnumDescription("右上方")] RightTop = 3, /// <summary> /// 左边 /// </summary> [EnumDescription("左边")] Left = 4, /// <summary> /// 正中 /// </summary> [EnumDescription("正中")] Middle = 5, /// <summary> /// 右边 /// </summary> [EnumDescription("右边")] Right = 6, /// <summary> /// 左下方 /// </summary> [EnumDescription("左下方")] LeftBottom = 7, /// <summary> /// 正下方 /// </summary> [EnumDescription("正下方")] Bottom = 8, /// <summary> /// 右下方 /// </summary> [EnumDescription("右下方")] RightBottom = 9 }} |
EnumHelper.cs 代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Reflection;using System.ComponentModel;namespace ImageWaterMark{ public class EnumHelper { /// <summary> /// 得到枚举所有字段上面的描述,缺点是如果某个字段没有描述,则对应值时会出错 /// </summary> /// <typeparam name="T">枚举类型</typeparam> /// <returns></returns> public static List<string> GetEnumDescription<T>() { Type t = typeof(T); if(!t.IsEnum) { throw new ArgumentException("泛型参数必须是枚举类型。"); } FieldInfo[] fieldInfo = t.GetFields(); List<string> result = new List<string>(); foreach (FieldInfo item in fieldInfo) { DescriptionAttribute[] attrObjs = (DescriptionAttribute[])item.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attrObjs != null && attrObjs.Length > 0) { result.Add(attrObjs[0].Description); } } return result; } }} |
EnumDescription.cs 代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
using System;using System.Reflection;using System.Collections;using System.Text;namespace ImageWaterMark{ /// <summary> /// 把枚举值按照指定的文本显示 /// <remarks> /// 一般通过枚举值的ToString()可以得到变量的文本, /// 但是有时候需要的到与之对应的更充分的文本, /// 这个类帮助达到此目的。 /// </remarks> /// </summary> /// <example> /// [EnumDescription("中文数字")] /// enum MyEnum /// { /// [EnumDescription("数字一")] /// One = 1, /// /// [EnumDescription("数字二")] /// Two, /// /// [EnumDescription("数字三")] /// Three /// } /// EnumDescription.GetEnumText(typeof(MyEnum)); /// EnumDescription.GetFieldText(MyEnum.Two); /// EnumDescription.GetFieldTexts(typeof(MyEnum)); /// </example> [AttributeUsage(AttributeTargets.Field | AttributeTargets.Enum)] public class EnumDescription : Attribute { private string enumDisplayText; private int enumRank; private FieldInfo fieldIno; /// <summary> /// 描述枚举值 /// </summary> /// <param name="enumDisplayText">描述内容</param> /// <param name="enumRank">排列顺序</param> public EnumDescription(string enumDisplayText, int enumRank) { this.enumDisplayText = enumDisplayText; this.enumRank = enumRank; } /// <summary> /// 描述枚举值,默认排序为5 /// </summary> /// <param name="enumDisplayText">描述内容</param> public EnumDescription(string enumDisplayText) : this(enumDisplayText, 5) { } public string EnumDisplayText { get { return this.enumDisplayText; } } public int EnumRank { get { return enumRank; } } public int EnumValue { get { return (int)fieldIno.GetValue(null); } } public string FieldName { get { return fieldIno.Name; } } /// <summary> /// 排序类型 /// </summary> public enum SortType { /// <summary> ///按枚举顺序默认排序 /// </summary> Default, /// <summary> /// 按描述值排序 /// </summary> DisplayText, /// <summary> /// 按排序熵 /// </summary> Rank } private static System.Collections.Hashtable cachedEnum = new Hashtable(); /// <summary> /// 得到对枚举的描述文本 /// </summary> /// <param name="enumType">枚举类型</param> /// <returns></returns> public static string GetEnumText(Type enumType) { EnumDescription[] eds = (EnumDescription[])enumType.GetCustomAttributes(typeof(EnumDescription), false); if (eds.Length != 1) return string.Empty; return eds[0].EnumDisplayText; } /// <summary> /// 获得指定枚举类型中,指定值的描述文本。 /// </summary> /// <param name="enumValue">枚举值,不要作任何类型转换</param> /// <returns>描述字符串</returns> public static string GetFieldText(object enumValue) { EnumDescription[] descriptions = GetFieldTexts(enumValue.GetType(), SortType.Default); foreach (EnumDescription ed in descriptions) { if (ed.fieldIno.Name == enumValue.ToString()) return ed.EnumDisplayText; } return string.Empty; } /// <summary> /// 得到枚举类型定义的所有文本,按定义的顺序返回 /// </summary> /// <exception cref="NotSupportedException"></exception> /// <param name="enumType">枚举类型</param> /// <returns>所有定义的文本</returns> public static EnumDescription[] GetFieldTexts(Type enumType) { return GetFieldTexts(enumType, SortType.Default); } /// <summary> /// 得到枚举类型定义的所有文本 /// </summary> /// <exception cref="NotSupportedException"></exception> /// <param name="enumType">枚举类型</param> /// <param name="sortType">指定排序类型</param> /// <returns>所有定义的文本</returns> public static EnumDescription[] GetFieldTexts(Type enumType, SortType sortType) { EnumDescription[] descriptions = null; //缓存中没有找到,通过反射获得字段的描述信息 if (cachedEnum.Contains(enumType.FullName) == false) { FieldInfo[] fields = enumType.GetFields(); ArrayList edAL = new ArrayList(); foreach (FieldInfo fi in fields) { object[] eds = fi.GetCustomAttributes(typeof(EnumDescription), false); if (eds.Length != 1) continue; ((EnumDescription)eds[0]).fieldIno = fi; edAL.Add(eds[0]); } cachedEnum.Add(enumType.FullName, (EnumDescription[])edAL.ToArray(typeof(EnumDescription))); } descriptions = (EnumDescription[])cachedEnum[enumType.FullName]; if (descriptions.Length <= 0) throw new NotSupportedException("枚举类型[" + enumType.Name + "]未定义属性EnumValueDescription"); //按指定的属性冒泡排序 for (int m = 0; m < descriptions.Length; m++) { //默认就不排序了 if (sortType == SortType.Default) break; for (int n = m; n < descriptions.Length; n++) { EnumDescription temp; bool swap = false; switch (sortType) { case SortType.Default: break; case SortType.DisplayText: if (string.Compare(descriptions[m].EnumDisplayText, descriptions[n].EnumDisplayText) > 0) swap = true; break; case SortType.Rank: if (descriptions[m].EnumRank > descriptions[n].EnumRank) swap = true; break; } if (swap) { temp = descriptions[m]; descriptions[m] = descriptions[n]; descriptions[n] = temp; } } } return descriptions; } /* 用法 */ /* string txt = EnumDescription.GetEnumText(typeof(OrderStateEnum)); string txt = EnumDescription.GetFieldText(OrderStateEnum.Processing); EnumDescription[] des = EnumDescription.GetFieldTexts(typeof(OrderStateEnum)) public static EnumDescription[] GetFieldTexts( Type enumType, SortType sortType ) */ }} |
CoverWaterImage.cs 代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Drawing;using System.IO;namespace ImageWaterMark{ public class CoverWaterImage { private const string waterMarkImagePath = "~/images/waterMark.png"; // 水印图片虚拟路径 /// <summary> /// 给图片加水印 /// </summary> /// <param name="physicalImagePath">需要加水印的图片的物理路径</param> /// <param name="savedPhysicalPath">保存后的水印图片的物理路径</param> /// <param name="errorMessage">操作失败后显示的错误信息</param> /// <param name="imagePosition">水印要加入的地方</param> /// <returns>是否成功,true 表示成功</returns> public static bool MakeCoverWaterImage(string physicalImagePath, string savedPhysicalPath, out string errorMessage, ImagePosition imagePosition) { errorMessage = string.Empty; if (File.Exists(physicalImagePath)) { //文件存在 Image coverImage = Image.FromFile(physicalImagePath); Image waterMarkImage = Image.FromFile(HttpContext.Current.Server.MapPath(waterMarkImagePath)); if (coverImage.Width <= (waterMarkImage.Width + 10) || coverImage.Height <= (waterMarkImage.Height + 10)) { errorMessage = "图片的宽度或高度太小。"; waterMarkImage.Dispose(); coverImage.Dispose(); return false; } Graphics gh = null; try { gh = Graphics.FromImage(coverImage); } catch (Exception) { errorMessage = "画布创建失败!"; waterMarkImage.Dispose(); coverImage.Dispose(); return false; } float x; float y; float xOffset = 10; //宽度偏移量 float yOffset = 10; //高度偏移量 switch (imagePosition) { case ImagePosition.Bottom: //正下方 x = ((float)coverImage.Width - waterMarkImage.Width) / 2; y = coverImage.Height - waterMarkImage.Height - yOffset; break; case ImagePosition.LeftBottom: //左下方 x = xOffset; y = coverImage.Height - waterMarkImage.Height - yOffset; break; case ImagePosition.Right: //右方 x = coverImage.Width - waterMarkImage.Width - xOffset; y = ((float)coverImage.Height - waterMarkImage.Height) / 2; break; case ImagePosition.Middle: //正中 x = ((float)coverImage.Width - waterMarkImage.Width) / 2; y = ((float)coverImage.Height - waterMarkImage.Height) / 2; break; case ImagePosition.Left: //左边 x = xOffset; y = ((float)coverImage.Height - waterMarkImage.Height) / 2; break; case ImagePosition.RightTop: //右上方 x = coverImage.Width - waterMarkImage.Width - xOffset; y = yOffset; break; case ImagePosition.Top: //正上方 x = ((float)coverImage.Width - waterMarkImage.Width) / 2; y = yOffset; break; case ImagePosition.LeftTop: //左上方 x = xOffset; y = yOffset; break; case ImagePosition.Default: case ImagePosition.RightBottom: default: //右下角 x = coverImage.Width - waterMarkImage.Width - xOffset; y = coverImage.Height - waterMarkImage.Height - yOffset; break; } gh.DrawImage(waterMarkImage, x, y, waterMarkImage.Width, waterMarkImage.Height); gh.Save(); gh.Dispose(); waterMarkImage.Dispose(); coverImage.Save(savedPhysicalPath, System.Drawing.Imaging.ImageFormat.Jpeg); coverImage.Dispose(); } else { //文件不存在 return false; } return true; } }} |
结果效果图:

提交后效果图:

重新裁剪后:
等待更新...
附件下载:

浙公网安备 33010602011771号