基于WebImage的图片上传工具类
程序员文章站
2022-07-02 14:50:07
基于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(1024 * 1024 * 2, "/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 > 0 ? waterOption.Width : img.Width; // int h = waterOption.Height > 0 ? waterOption.Height : img.Height; var h = waterOption.Height; if (h == 0) { 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 = 0, Ext = "", ImageUrl = "", ThumbUrl = "", Width = 0, Height = 0 }; } } } #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; // 0:横向;1:纵向 var thumbWidth = 0; var thumbHeight = 0; if (wScale >= hScale) { direct = 0; thumbHeight = option.Height + 2; thumbWidth = option.Height * source.Width / source.Height; } else { direct = 1; thumbWidth = option.Width + 2; thumbHeight = option.Width * source.Height / source.Width; } thumb = source.Resize(thumbWidth, thumbHeight, false, false); if (direct == 0) { var py = (thumbWidth - option.Width) / 2; thumb = thumb.Crop(1, py, 1, py); } else { var py = (thumbHeight - option.Height) / 2; thumb = thumb.Crop(py, 1, py, 1); } } } 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; } = 180; /// <summary> /// 缩略图高度 /// </summary> public int Height { get; set; } = 180; /// <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; } = 0; /// <summary> /// 水印图片的高度,仅当水印类型为图片时有效 /// </summary> public int Height { get; set; } = 0; /// <summary> /// 水印的透明度,100为完全不透明,0为完全透明 /// </summary> public int Opacity { get; set; } = 50; /// <summary> /// 边距大小 /// </summary> public int Padding { get; set; } = 5; /// <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; } = 12; /// <summary> /// 水印文本的文字颜色,仅当水印类型为文本时有效 /// 赋值类似于 "White"、"Black" 或 "DarkBlue",或 "#RRGGBB" 或 "#RGB" 形式的十六进制值 /// </summary> public string FontColor { get; set; } = "Black"; } /// <summary> /// 图片上传结果码的枚举 /// </summary> public enum ImgUploadResultCode { 不受支持的文件类型 = 511, 文件大小超出限制 = 512, 文件不存在 = 514, 系统异常 = 500, 上传成功 = 200 } /// <summary> /// 水印类型的枚举 /// </summary> public enum WaterType { 文字 = 1, 图片 = 2 } }View Code
上面是工具的代码,调用例子如下:
1 [HttpPost] 2 public JsonResult ImageUpload() 3 { 4 if (HttpContext.Request.RequestType == "GET") 5 { 6 return Json(new ImgUploadResult { Code = ImgUploadResultCode.文件不存在 }); 7 } 8 9 ImgUploadResult result; 10 WebImage image = WebImage.GetImageFromRequest(""); 11 if (image == null) 12 { 13 return Json(new ImgUploadResult { Code = ImgUploadResultCode.文件不存在 }); 14 } 15 16 MvcImageUploader uploader = new MvcImageUploader(); 17 18 // 文字水印 19 result = uploader.UploadImage(image, true, true, 20 new ThumbOption { IsCrop = true }, 21 new WaterOption 22 { 23 Content = "这是文字水印", 24 FontFamily = "微软雅黑", 25 FontSize = 18, 26 FontColor = "#FF0000", 27 Padding = 30, 28 HorizontalPostion = "Center", 29 VerticalPostion = "Middle", 30 Opacity = 80 31 }); 32 33 // 图片水印 34 //result = uploader.UploadImage(image, true, true, 35 // new ThumbOption { IsCrop = true }, 36 // new WaterOption 37 // { 38 // Type = WaterType.图片, 39 // Content = "/Upload/Pics/201801/cctv1.jpg", 40 // HorizontalPostion = "Center", 41 // VerticalPostion = "Middle", 42 // Width = 150 43 // }); 44 return Json(result); 45 }
推荐阅读
-
基于WebUploader的图片上传解析
-
基于vue-upload-component封装一个图片上传组件的示例
-
C#编写了一个基于Lucene.Net的搜索引擎查询通用工具类:SearchEngineUtil
-
关于基于nginx+php组建的网站上传图片漏洞的修补方法
-
Android开发实现的IntentUtil跳转多功能工具类【包含视频、音频、图片、摄像头等操作功能】
-
基于GD2图形库的PHP生成图片缩略图类代码分享
-
基于php上传图片重命名的6种解决方法的详细介绍
-
基于HTML5的可预览多图片Ajax上传
-
PHP实现可添加水印与生成缩略图的图片处理工具类
-
微信小程序基于腾讯云对象存储的图片上传功能