VS目录:
代码如下:
Default.aspx 页面
<%@ 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">
<html xmlns="http://www.w3.org/1999/xhtml" >
<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 代码:
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 代码如下:
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 代码如下:
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 代码如下:
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 代码如下:
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 代码如下:
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;
}
}
}
结果效果图:
提交后效果图:
重新裁剪后:
等待更新...
附件下载:
欢迎您的评论! o(∩_∩)o