ASP.NET MVC在服务端把异步上传的图片裁剪成不同尺寸分别保存,并设置上传目录的尺寸限制
2014-11-13 10:51
591 查看
我曾经试过使用
JSAjaxFileUploader插件来把文件、照片以异步的方式上传,就像"MVC文件图片ajax上传轻量级解决方案,使用客户端JSAjaxFileUploader插件01-单文件上传"中说的,这种方法足够轻、足够好。但今天,要在前面的基础上再增加2个需求:1、异步判断上传的图片是否超过最大限制2、把上传的图片裁剪成大中小3张图片,分别保存,删除的时候一块被删除上传图片如果超出最大尺寸限制,终止上传,并报错误信息。前台上传图片,显示缩略图。在项目根目录下的指定文件夹
AjaxUpload中同时有了大中小3张图片。点击图片行的删除按钮或重新上传新的图片,原先的大中小3张图片一块被删除。重新上传新图片:在项目根目录下的指定文件夹
AjaxUpload中同时有了新的大中小3张图片。前端还是使用
JSAjaxFileUploader插件,后端使用
ImageResizer组件实现对图片的裁剪和保存。当前端拿到异步请求的返回结果后,需要显示图片、记录下图片的名称、错误信息等,可以把这些信息封装到
UploadFileResult类中,让服务端以json格式返回。
namespace MvcApplication1.Models
{
public class UploadFileResult
{
public string LargeFileName { get; set; } //带后缀名的图片名称,比如:20141112_large.jpg
public string MediumFileName { get; set; }
public string SmallFileName { get; set; }
public int Length { get; set; } //图片的字节数
public string Type { get; set; } //图片的类型:image/jpeg
public bool IsValid { get; set; } //用来判断是否超过尺寸最大限制
public string Message { get; set; }
public string LargeFilePath { get; set; } //图片的保存路径:~/AjaxUpload/20141112_large.jpg
public string MediumFilePath { get; set; }
public string SmallFilePath { get; set; }
}
}以上,○
LargeFileName用来保存裁剪大图的名称,类似"20141112_large.jpg",当前台需要删除图片的时候,还需要把这个图片名称传递给服务端,再到指定文件夹删除图片。○
LargeFilePath用来保存图片的路径,类似"~/AjaxUpload/20141112_large.jpg",前台显示图片的时候需要这个。○
IsValid为true表示可以裁剪保存图片,为false表示超过最大的尺寸限制,取消上传通过NuGet安装ImageResizer。安装完后,在"引用"下面多了一个ImageResizer组件。创建
HomeController,主要完成以下工作:1、接收前台上传图片,裁剪成大中小图片并分别保存2、接收前台需要删除的图片名称,在指定文件夹中同时删除大中小图片3、提供递归统计指定文件夹大小的方法......
using System;
using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.Mvc;
using ImageResizer;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult UploadFile()
{
//需要返回给前台的结果
List<UploadFileResult> results = new List<UploadFileResult>();
//遍历从前台传递而来的文件
foreach (string file in Request.Files)
{
//把每一个上传文件封装成HttpPostedFileBase
HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
//如果前台传来的文件集合中有null,继续遍历其他文件
if (hpf.ContentLength == 0 || hpf == null)
{
continue;
}
//给上传文件改名
string date = DateTime.Now.ToString("yyyyMMddhhmmss");
//目标文件夹的相对路径 ImageSize需要的格式
string pathForSaving = Server.MapPath("~/AjaxUpload/");
//目标文件夹的相对路径 统计文件夹大小需要的格式
string pathForSaving1 = Server.MapPath("~/AjaxUpload");
//保存文件并返回结果
if (this.CreateFolderIfNeeded(pathForSaving))
{
long currentSize = GetDirectoryLength(pathForSaving1);
//如果大于最大限制,直接返回json信息
//1M=1024*1024个字节
if (currentSize + hpf.ContentLength > 50 * 1024 * 1024)//最大允许50兆
{
results.Add(new UploadFileResult()
{
LargeFileName = "",
LargeFilePath = "",
MediumFileName = "",
MediumFilePath = "",
SmallFileName = "",
SmallFilePath = "",
IsValid = false,
Length = hpf.ContentLength,
Message = "超过最大限制无法上传",
Type = hpf.ContentType
});
}
else //如果小于最大限制,才保存大中小图片
{
//保存图片的各种版本:小图,中图,大图
var versions = new Dictionary<string, string>();
versions.Add("_small", "maxwidth=50&maxheight=50&format=jpg");
versions.Add("_medium", "maxwidth=200&maxheight=200&format=jpg");
versions.Add("_large", "maxwidth=600&maxheight=600&format=jpg");
//保存各个版本的缩略图
foreach (var key in versions.Keys)
{
hpf.InputStream.Seek(0, SeekOrigin.Begin);
ImageBuilder.Current.Build(new ImageJob(
hpf.InputStream,
pathForSaving + date + key, //不带后缀名的图片名称
new Instructions(versions[key]),
false,//是否保留原图
true));//是否增加后缀
}
results.Add(new UploadFileResult()
{
LargeFileName = date + "_large" + ".jpg",
LargeFilePath = Url.Content(String.Format("~/AjaxUpload/{0}", date + "_large" + ".jpg")),
MediumFileName = date + "_medium" + ".jpg",
MediumFilePath = Url.Content(String.Format("~/AjaxUpload/{0}", date + "_mediume" + ".jpg")),
SmallFileName = date + "_small" + ".jpg",
SmallFilePath = Url.Content(String.Format("~/AjaxUpload/{0}", date + "_small" + ".jpg")),
IsValid = true,
Length = hpf.ContentLength,
Message = "上传成功",
Type = hpf.ContentType
});
}
}
}
//单文件上传,实际上results中只有一个元素
return Json(new
{
largename = results[0].LargeFileName,
largepath = results[0].LargeFilePath,
mediumname = results[0].MediumFileName,
mediumpath = results[0].MediumFilePath,
smallname = results[0].SmallFileName,
smallpath = results[0].SmallFilePath,
type = results[0].Type,
size = string.Format("{0} bytes", results[0].Length),
msg = results[0].Message,
isvalid = results[0].IsValid
});
}
//根据文件名称删除文件
[HttpPost]
public ActionResult DeleteFileByNames(string largename, string mediumname, string smallname)
{
string pathForSaving = Server.MapPath("~/AjaxUpload");
System.IO.File.Delete(Path.Combine(pathForSaving, largename));
System.IO.File.Delete(Path.Combine(pathForSaving, mediumname));
System.IO.File.Delete(Path.Combine(pathForSaving, smallname));
return Json(new
{
msg = true
});
}
/// <summary>
/// 根据目标文件夹的相对路径创建文件夹
/// 如果目标文件夹不存在,就创建;存在就不创建
/// 只有在创建目标文件夹发生异常的时候才返回false
/// </summary>
/// <param name="path">目标文件夹的相对路径</param>
/// <returns></returns>
private bool CreateFolderIfNeeded(string path)
{
bool result = true;
if (!Directory.Exists(path))
{
try
{
Directory.CreateDirectory(path);
}
catch (Exception)
{
result = false;
}
}
return result;
}
/// <summary>
/// 根据目标文件夹的相对路径递归计算该文件夹的大小
/// </summary>
/// <param name="path">用相对路径表示的目标文件夹</param>
/// <returns></returns>
private static long GetDirectoryLength(string path)
{
//如果目标文件夹不存在就返回0
if (!Directory.Exists(path))
{
return 0;
}
long size = 0;
//获取目标文件夹的信息
DirectoryInfo di = new DirectoryInfo(path);
//遍历目标文件夹下的所有文件遍历累计每个文件的大小
foreach (FileInfo fi in di.GetFiles())
{
size += fi.Length;
}
//获取目标文件夹下的所有子文件夹
DirectoryInfo[] dis = di.GetDirectories();
//如果确实有子文件夹
if (dis.Length > 0)
{
//遍历这些子文件夹
for (int i = 0; i < dis.Length; i++)
{
//递归统计累计大小
size += GetDirectoryLength(dis[i].FullName);
}
}
return size;
}
}
}以上,○
UploadFile方法中,通过
Request.Files拿到所有的上传图片,然后遍历这些图片,通过
Request.Files[key]获取某个图片,把该图片转换成
HttpPostedFileBase类型。在裁剪保存图片之前,使用
GetDirectoryLength方法获取当前文件夹的尺寸,如果没有超过尺寸的最大限制,就使用
ImageResizer把图片裁剪成大中小3张图片,并分别保存。○
DeleteFileByNames方法中,从前台接收大中小图片的名称,再到根目录下的指定文件夹
AjaxUpload中删除大中小3张图片。在
_Layout.cshtml中引入相关css、js文件。
JQuery.JSAjaxFileUploaderSingle.js文件已经做了汉化,详细参考这里。
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
<link href="~/Content/JSAjaxFileUploader/JQuery.JSAjaxFileUploader.css" rel="stylesheet" />
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
<script src="~/JSAjaxFileUploader/JQuery.JSAjaxFileUploaderSingle.js"></script>
</head>
<body>
@RenderBody()
@RenderSection("scripts", required: false)
</body>创建
Home/Index.cshtml视图,主要工作包括:1、处理图片上传,每次上传前需要把原先的3张图片删除,如果上传成功显示小图的缩略图,如果上传失败,给出错误提示。2、提供一个动态创建图片行表格的方法3、提供一个删除大中小图片的方法,向服务端发送3张图片的名称......
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<style type="text/css">
#tb table {
border-collapse: collapse;
width: 600px;
}
#tb td {
text-align: center;
padding-top: 5px;
width: 25%;
}
#tb tr {
background-color: #E3E3E3;
line-height: 35px;
}
.limit {
color: red;
}
</style>
<div id="testId"></div>
<div id="tb">
<table id="tbl">
<tbody>
</tbody>
</table>
</div>
<div>
<span class="limit"></span>
</div>
@section scripts
{
<script type="text/javascript">
$(function() {
//隐藏显示图片的表格
$('#tbl').hide();
//图片上传
$('#testId').JSAjaxFileUploader({
uploadUrl: '@Url.Action("UploadFile","Home")',
inputText: '选择上传文件',
//fileName: 'photo',
maxFileSize: 512000, //Max 500 KB file 1kb=1024字节
allowExt: 'gif|jpg|jpeg|png',
zoomPreview: false,
zoomWidth: 360,
zoomHeight: 360,
beforesend: function (file) {//每次点击都要删除原先的
if ($('.largeImgName').text() != "" && $('.mediumImgName').text() != "" && $('.smallImgName').text() != "") {
deleteImg();
$('#tbl').hide();
}
},
success: function (data) {
if (!data.isvalid) { //如果尺寸超过最大限制
$('.limit').css("display", "block");
$('.limit').text(data.msg);
return;
} else {
$('.limit').css("display", "none");
createTableTr();
$('#tbl').show();
$('.showImg').attr("src", data.smallpath);//显示小图片
$('.largeImgName').text(data.largename); //显示大图的名称
$('.mediumImgName').text(data.mediumname); //显示中图的名称
$('.smallImgName').text(data.smallname); //显示小图的名称
}
},
error: function (data) {
alert(data.msg);
}
});
//点击删除链接删除刚上传图片
$('#tbl').on("click", ".delImg", function () {
deleteImg();
//window.location.reload();
});
});
//创建表格
function createTableTr() {
var table = $('#tbl');
table.append("<tr><td><img class='showImg'/></td><td colspan='2'><span class='largeImgName'></span><br/><span class='mediumImgName'></span><br/><span class='smallImgName'></span></td><td><a class='delImg' href='javascript:void(0)'>删除</a></td></tr>");
}
//删除图片方法:点击删除链接或上传新图片删除原先图片用到
function deleteImg() {
$.ajax({
cache: false,
url: '@Url.Action("DeleteFileByNames", "Home")',
type: "POST",
data: { largename: $('.largeImgName').text(), mediumname: $('.mediumImgName').text(), smallname: $('.smallImgName').text() },
success: function (data) {
if (data.msg) {
//alert("图片删除成功");
$('.delImg').parent().parent().remove();
}
},
error: function (jqXhr, textStatus, errorThrown) {
alert("出错了 '" + jqXhr.status + "' (状态: '" + textStatus + "', 错误为: '" + errorThrown + "')");
}
});
}
</script>
}
相关文章推荐
- ASP.NET MVC在服务端把异步上传的图片裁剪成不同尺寸分别保存,并设置上传目录的尺寸限制
- ASP.NET MVC在服务端把异步上传的图片裁剪成不同尺寸分别保存,并设置上传目录的尺寸限制
- 在ASP.NET MVC下实现单个图片上传, 客户端服务端双重限制图片大小和格式, 服务端裁剪图片
- ASP.NET MVC异步上传图片和富文本编辑器的使用详解
- springMVC + ajaxfileupload异步上传图片预览,裁剪并保存图片
- springMVC + ajaxfileupload异步上传图片预览,裁剪并保存图片
- springMVC + ajaxfileupload异步上传图片预览,裁剪并保存图片
- ASP.NET MVC异步上传图片和富文本编辑器的使用详解
- springMVC + ajaxfileupload异步上传图片预览,裁剪并保存图片
- ASP.NET MVC异步上传图片和富文本编辑器的使用详解
- 安卓客户端上传图片到asp.net mvc服务器,服务端接收不到图片,求指点
- ASP.net之图片上传(保存在SQL数据库)
- ASP.NET上传图片,服务器端验证,宽度,高度,文件类型,尺寸,文件大小,图片上传,图片格式检查
- 使用Jcrop实现图片上传、剪裁和保存(ASP.NET)
- asp.net 自定义控件实现无刷新上传图片,立即显示缩略图,保存图片缩略图
- 在ASP.NET MVC中实现大文件异步上传(2)
- asp.net mvc下使用xheditor上传文件无法保存的解决方案
- asp.net mvc 上传大文件保存的解决方法
- 在ASP.NET MVC中实现大文件异步上传(2)
- dhl: ASP.NET MVC1.0 的图片(文件)上传功能