基于WebImage的图片上传工具类

支持缩略图和水印。

using System;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Helpers; namespace HZC.Util.Mvc
{
public class MvcImageUploader
{
#region 字段
private string[] _imageExts = new string[] { "jpg", "jpeg", "png", "gif", "bmp" }; // 允许上传的图片类型
private string _basePath;
private string _baseLocalPath;
private int _fileLimitSize;
#endregion #region 构造函数
/// <summary>
/// MVC图片上传工具
/// </summary>
public MvcImageUploader() : this( * * , "/Upload/Pics")
{ } /// <summary>
/// MVC图片上传工具
/// </summary>
/// <param name="fileLimitSize">图片最大限制</param>
public MvcImageUploader(int fileLimitSize) : this(fileLimitSize, "/Upload/Pics")
{ } /// <summary>
/// MVC图片上传工具
/// </summary>
/// <param name="fileLimitSize">图片最大限制,默认2M</param>
/// <param name="basePath">图片上传路径,默认为 ~/Upload/Pics </param>
public MvcImageUploader(int fileLimitSize, string basePath)
{
_basePath = basePath;
_fileLimitSize = fileLimitSize;
_baseLocalPath = GetServerPath(_basePath);
}
#endregion #region 上传
public ImgUploadResult UploadImage(WebImage image, bool isThumb = true, bool isWater = false,
ThumbOption thumbOption = null, WaterOption waterOption = null)
{
if (image == null)
{
return new ImgUploadResult {
Code = ImgUploadResultCode.文件不存在,
Message = "请求中未检测到文件"
};
}
else
{
try
{
string extName = Path.GetExtension(image.FileName).ToLower();
int size = image.GetBytes().Length;
int width = image.Width;
int height = image.Height; // 验证文件类型
if (!ValidFileSize(size))
{
return new ImgUploadResult
{
Code = ImgUploadResultCode.文件大小超出限制,
Message = "文件大小超出限制"
};
} // 验证文件大小
if (!ValidExtName(extName))
{
return new ImgUploadResult
{
Code = ImgUploadResultCode.不受支持的文件类型,
Message = "不受支持的文件类型"
};
} var result = new ImgUploadResult(); // 图片位置相关
var folderName = GetImageUploadFolder(); // 图片文件夹名称
var newFileName = GetNewFileName(extName); // 随机生成的图片名称
var newFolderPath = Path.Combine(_baseLocalPath, folderName); // 图片文件夹在服务器上的物理路径
var newFilePath = Path.Combine(newFolderPath, newFileName); // 图片在服务器上保存的物理路径
var thumbFilePath = Path.Combine(_baseLocalPath, // 缩略图在服务器上保存的物理路径
folderName, "Thumbs", newFileName); if (!Directory.Exists(newFolderPath)) // 校验|创建图片文件夹
{
Directory.CreateDirectory(newFolderPath);
Directory.CreateDirectory(Path.Combine(newFolderPath, "Thumbs"));
} // 获取水印
if (isWater)
{
if (waterOption != null)
{
if (waterOption.Type == WaterType.图片)
{
// 图片水印
if (!string.IsNullOrWhiteSpace(waterOption.Content))
{
var path = GetServerPath(waterOption.Content);
if (File.Exists(path))
{
WebImage img = new WebImage(path);
int w = waterOption.Width > ? waterOption.Width : img.Width;
// int h = waterOption.Height > 0 ? waterOption.Height : img.Height;
var h = waterOption.Height;
if (h == )
{
h = img.Height * w / img.Width;
} image.AddImageWatermark(img, w, h,
waterOption.HorizontalPostion, waterOption.VerticalPostion,
waterOption.Opacity, waterOption.Padding);
}
}
}
else
{
// 文字水印
if (!string.IsNullOrWhiteSpace(waterOption.Content))
{ image.AddTextWatermark(waterOption.Content, waterOption.FontColor, waterOption.FontSize, waterOption.FontStyle,
waterOption.FontFamily, waterOption.HorizontalPostion, waterOption.VerticalPostion,
waterOption.Opacity, waterOption.Padding);
}
}
}
} image.Save(newFilePath); // 保存文件 result.Code = ImgUploadResultCode.上传成功;
result.Message = "";
result.ImageUrl = _basePath + "/" + folderName + "/" + newFileName;
result.ThumbUrl = "";
result.Size = size;
result.Width = width;
result.Height = height;
result.Ext = extName; // 缩略图
if (isThumb)
{
var thumb = MakeThumb(image, thumbOption);
thumb.Save(thumbFilePath);
result.ThumbUrl = _basePath + "/" + folderName + "/Thumbs/" + newFileName;
} return result;
}
catch (Exception ex)
{
SimpleLog.WriteErrorLogAsyn("UploaderController.Image", ex.Message + ":" + ex.StackTrace);
return new ImgUploadResult
{
Code = ImgUploadResultCode.系统异常,
Message = ex.Message + ":" + ex.StackTrace,
Size = ,
Ext = "",
ImageUrl = "",
ThumbUrl = "",
Width = ,
Height =
};
}
}
}
#endregion #region 生成缩略图
private WebImage MakeThumb(WebImage source, ThumbOption option = null)
{
if (option == null)
{
option = new ThumbOption();
} WebImage thumb;
if (option.IsCrop)
{
if (source.Width <= option.Width || source.Height <= option.Height)
{
thumb = source.Resize(option.Width, option.Height, true, true);
}
else
{
var wScale = source.Width / option.Width;
var hScale = source.Height / option.Height; var direct = ; // 0:横向;1:纵向 var thumbWidth = ;
var thumbHeight = ; if (wScale >= hScale)
{
direct = ;
thumbHeight = option.Height + ;
thumbWidth = option.Height * source.Width / source.Height;
}
else
{
direct = ;
thumbWidth = option.Width + ;
thumbHeight = option.Width * source.Height / source.Width;
} thumb = source.Resize(thumbWidth, thumbHeight, false, false); if (direct == )
{
var py = (thumbWidth - option.Width) / ;
thumb = thumb.Crop(, py, , py);
}
else
{
var py = (thumbHeight - option.Height) / ;
thumb = thumb.Crop(py, , py, );
}
}
}
else
{
thumb = source.Resize(option.Width, option.Height, true, true);
}
return thumb;
}
#endregion #region 获取图片的上传文件夹
private string GetImageUploadFolder()
{
string folderName = DateTime.Today.ToString("yyyyMM");
return folderName;
}
#endregion #region 获取文件上传后的文件名称
private string GetNewFileName(string ext)
{
string fileName = Path.GetRandomFileName();
return fileName + "." + ext;
}
#endregion #region 验证文件扩展名
private bool ValidExtName(string ext)
{
return _imageExts.Contains(ext);
}
#endregion #region 验证文件大小
private bool ValidFileSize(int size)
{
return size <= _fileLimitSize;
}
#endregion #region 获取指定路径在服务器上的位置
private string GetServerPath(string url)
{
url = url.ToLower();
if (url.StartsWith("http://") || url.StartsWith("https://"))
{
return url;
}
else if (HttpContext.Current != null)
{
return HttpContext.Current.Server.MapPath(url);
}
else
{
return string.Empty;
}
}
#endregion
} /// <summary>
/// 图片上传结果
/// </summary>
public class ImgUploadResult
{
/// <summary>
/// 结果码
/// </summary>
public ImgUploadResultCode Code { get; set; } /// <summary>
/// 消息
/// </summary>
public string Message { get; set; } /// <summary>
/// 图片上传成功后的相对路径,如:/Upload/Pic/...
/// </summary>
public string ImageUrl { get; set; } /// <summary>
/// 缩略图的相对路径
/// </summary>
public string ThumbUrl { get; set; } /// <summary>
/// 图片的扩展名
/// </summary>
public string Ext { get; set; } /// <summary>
/// 图片的大小
/// </summary>
public int Size { get; set; } /// <summary>
/// 图片的宽度
/// </summary>
public int Width { get; set; } /// <summary>
/// 图片的高度
/// </summary>
public int Height { get; set; }
} /// <summary>
/// 缩略图配置选项
/// </summary>
public class ThumbOption
{
/// <summary>
/// 缩略图宽度
/// </summary>
public int Width { get; set; } = ; /// <summary>
/// 缩略图高度
/// </summary>
public int Height { get; set; } = ; /// <summary>
/// 是否保持图片的宽高比
/// </summary>
public bool IsPreserveAspectRatio { get; set; } = true; /// <summary>
/// 是否阻止放大图片
/// </summary>
public bool IsPreventEnlarge { get; set; } = true; /// <summary>
/// 是否裁剪图片,
/// 如果裁剪,图片短边适应缩略图尺寸,自动缩放长边,并根据缩略图尺寸从中心裁剪长边
/// 如果裁剪,图片长边适应缩略图尺寸,短边按比例缩放
/// </summary>
public bool IsCrop { get; set; } = false;
} /// <summary>
/// 水印配置选项
/// </summary>
public class WaterOption
{
/// <summary>
/// 水印类型,图片|文字
/// </summary>
public WaterType Type { get; set; } /// <summary>
/// 水印内容,
/// 类型为图片时,传入水印图片相对根目录的路径,如:/Upload/Pics/201801/xxx.jpg
/// 类型为文字时,传入水印的文字
/// </summary>
public string Content { get; set; } /// <summary>
/// 水印的水平位置,
/// 可选为 Left|Center|Right
/// </summary>
public string HorizontalPostion { get; set; } = "Right"; /// <summary>
/// 水印的垂直位置,
/// 可选为 Top|Middle|Bottom
/// </summary>
public string VerticalPostion { get; set; } = "Bottom"; /// <summary>
/// 水印图片的宽度,仅当水印类型为图片时有效
/// </summary>
public int Width { get; set; } = ; /// <summary>
/// 水印图片的高度,仅当水印类型为图片时有效
/// </summary>
public int Height { get; set; } = ; /// <summary>
/// 水印的透明度,100为完全不透明,0为完全透明
/// </summary>
public int Opacity { get; set; } = ; /// <summary>
/// 边距大小
/// </summary>
public int Padding { get; set; } = ; /// <summary>
/// 水印文本的字体,仅当水印类型为文本时有效
/// 注意,若指定字体在服务器上不存在,会抛出报错
/// </summary>
public string FontFamily { get; set; } = "Microsoft Sans Serif"; /// <summary>
/// 水印文本的样式,仅当水印类型为文本时有效
/// 可选项目 Regular|Bold|Italic|Strikeout|Underline
/// </summary>
public string FontStyle { get; set; } = "Regular"; /// <summary>
/// 水印文本的文字大小,仅当水印类型为文本时有效
/// </summary>
public int FontSize { get; set; } = ; /// <summary>
/// 水印文本的文字颜色,仅当水印类型为文本时有效
/// 赋值类似于 "White"、"Black" 或 "DarkBlue",或 "#RRGGBB" 或 "#RGB" 形式的十六进制值
/// </summary>
public string FontColor { get; set; } = "Black";
} /// <summary>
/// 图片上传结果码的枚举
/// </summary>
public enum ImgUploadResultCode
{
不受支持的文件类型 = ,
文件大小超出限制 = ,
文件不存在 = ,
系统异常 = ,
上传成功 =
} /// <summary>
/// 水印类型的枚举
/// </summary>
public enum WaterType
{
文字 = ,
图片 =
}
}

上面是工具的代码,调用例子如下:

 [HttpPost]
public JsonResult ImageUpload()
{
if (HttpContext.Request.RequestType == "GET")
{
return Json(new ImgUploadResult { Code = ImgUploadResultCode.文件不存在 });
} ImgUploadResult result;
WebImage image = WebImage.GetImageFromRequest("");
if (image == null)
{
return Json(new ImgUploadResult { Code = ImgUploadResultCode.文件不存在 });
} MvcImageUploader uploader = new MvcImageUploader(); // 文字水印
result = uploader.UploadImage(image, true, true,
new ThumbOption { IsCrop = true },
new WaterOption
{
Content = "这是文字水印",
FontFamily = "微软雅黑",
FontSize = ,
FontColor = "#FF0000",
Padding = ,
HorizontalPostion = "Center",
VerticalPostion = "Middle",
Opacity =
}); // 图片水印
//result = uploader.UploadImage(image, true, true,
// new ThumbOption { IsCrop = true },
// new WaterOption
// {
// Type = WaterType.图片,
// Content = "/Upload/Pics/201801/cctv1.jpg",
// HorizontalPostion = "Center",
// VerticalPostion = "Middle",
// Width = 150
// });
return Json(result);
}
上一篇:android get或post及HttpClient与服务器数据交互


下一篇:SharePoint 2013技巧分享系列 - 隐藏Blog和Apps左侧导航菜单