支持缩略图和水印。

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);
}

基于WebImage的图片上传工具类的更多相关文章

  1. PHP 图片上传工具类(支持多文件上传)

    ====================ImageUploadTool======================== <?php class ImageUploadTool { private ...

  2. ASP.NET 图片上传工具类 upload image简单好用功能齐全

    使用方法: UploadImage ui = new UploadImage(); /***可选参数***/ ui.SetWordWater = "哈哈";//文字水印 // ui ...

  3. spring mvc 文件上传工具类

    虽然文件上传在框架中,已经不是什么困难的事情了,但自己还是开发了一个文件上传工具类,是基于springmvc文件上传的. 工具类只需要传入需要的两个参数,就可以上传到任何想要上传的路径: 参数1:Ht ...

  4. spring boot 文件上传工具类(bug 已修改)

    以前的文件上传都是之前前辈写的,现在自己来写一个,大家可以看看,有什么问题可以在评论中提出来. 写的这个文件上传是在spring boot 2.0中测试的,测试了,可以正常上传,下面贴代码 第一步:引 ...

  5. 文件上传工具类 UploadUtil.java

    package com.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ja ...

  6. FastDFS 文件上传工具类

    FastDFS文件上传工具类 import org.csource.common.NameValuePair; import org.csource.fastdfs.ClientGlobal; imp ...

  7. AFNetworking网络请求与图片上传工具(POST)

    AFNetworking网络请求与图片上传工具(POST) .h文件 #import <Foundation/Foundation.h> /** 成功Block */ typedef vo ...

  8. 基于Jcrop的图片上传裁剪加预览

    最近自己没事的时候研究了下图片上传,发现之前写的是有bug的,这里自己重新写了一个! 1.页面结构 <!DOCTYPE html> <html lang="en" ...

  9. [图床神器]Windows下的图片上传工具MPic

    最近用hexo在github上搭建了一个静态博客,开始几天用起来感觉还挺好的,但是用了些天就觉得每次写文章插入图片就非常麻烦,而且如果图片多了的话上传和访问就很慢了.后来网上看了下发现mac下有款ip ...

随机推荐

  1. unbutu下wireshark编译安装(已更新)

    今天下午在ubuntu下进行编译安装wireshark,过程中出了很多错误,但最终安装成功了,这里写下自己的安装步骤和方法,有参考博文的安装编译方法,也有自己的总结和心得. 1 安装编译工具 $sud ...

  2. HttpUploader6.2-process版本

    1.优化JS逻辑,在上传前先同步相同文件进度,提高多用户上传效率. 2.优化文件块保存逻辑,减少相同文件块的写入操作,减少服务器IO操作,提高上传效率.   js变化: up6.js新增UrlQuer ...

  3. 编写高质量代码改善C#程序的157个建议——建议10: 创建对象时需要考虑是否实现比较器

    建议10: 创建对象时需要考虑是否实现比较器 有对象的地方就会存在比较,在.NET的世界中也一样.举个最简单的例子,在UI中,有一个10个人的Salary列表.根据排序的需要,列表要支持针对基本工资来 ...

  4. APUE(1)----UNIX基础知识

    一.UNIX体系结构 所有操作系统都为他们所运行的程序提供服务,典型的服务包括:执行新程序.打开文件.读文件.分配存储区等.严格意义上来说,操作系统可以定义为一种软件,它控制计算机硬件资源,提供程序运 ...

  5. 简单工厂(Simple Factory)模式

    工厂模式专门负责将大量有共同接口的类实例化.工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类.工厂模式有以下几种形态: 简单工厂(Simple Factory)模式 工厂方法(F ...

  6. 文字相对于 div 垂直居中

    通用方法 height  跟line-height div{ border: 1px solid black; text-align: left; height: 200px; line-height ...

  7. Graphics 小记

    1.切图 drowg.DrawImage(productImg1, new System.Drawing.Rectangle(30, 30, 300, 300), new System.Drawing ...

  8. .Net Mvc 四种过滤器

    一.授权过滤器:AuthorizationFilters 二.动作过滤:ActionFilters 三.响应过滤:ResultFilters 四.异常过滤:ExceptionFilters ===== ...

  9. Visual Studio 2015 开发 ASP.NET 5

    在以往微软发布或更新 Visual Studio 版本时,我们开发 ASP.NET 应用程序,带给我们的变化其实并不是很大,或者说你根本就感受不到变化,你感受到的只是下载安装了几个 G 的 Updat ...

  10. 使用 typescript ,提升 vue 项目的开发体验(1)

    此文已由作者张汉锐授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 前言:对于我们而言,typescript 更像一个工具 官方指南 从 vue2.5 之后,vue 对 ts ...