zoukankan      html  css  js  c++  java
  • 基于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         }
  • 相关阅读:
    Android SwitchButton(滑动开关)
    创建您自己的Maven模板
    Bag标签成一条线的代码来实现中国字
    rabbitmq的java简单的实现
    【七】注入框架RoboGuice使用:(Your First Custom Binding)
    Sqlmap渗透测试是常用语句
    Android NOtification 使用(震动 闪屏 铃声)
    Android loader 详解
    Android实现获取本机中所有图片
    Android保存图片到系统图库
  • 原文地址:https://www.cnblogs.com/diwu0510/p/8261039.html
Copyright © 2011-2022 走看看