[ASP.net MVC 4] 使用jQuery imgAreaSelect實現facebook的大頭照圖片剪裁功能
前言
圖片剪裁功能,使用者拖拉縮放一個選擇區域(selection area)
按下確定鈕,將該選擇區域給裁剪下來
基本原理:
先上傳一張原始圖片
jQuery Plugin幫忙弄出selection area效果,並回傳selection area的座標和寬高
然後我們可以用hidden欄位記下座標值和寬高,把資料送到Server端,Server端再用System.Drawing.Graphics的DrawImage()方法對原始圖檔把selection area裁切下來存檔即可。
以上動作可以在同一頁面完成,不過實際運用在專案上發現,很多地方都要加這種裁切功能的話,最好還是另外抽出一個頁面
然後再用window.open()或jQuery fancybox還是jQuery colorbox去開啟該頁面來處理圖片
實作
第一步先引用jQuery核心函式庫
再去imgAreaSelect - image selection-cropping jQuery plugin - odyniec.net官網 下載.zip壓縮檔
解壓後把裡面css資料夾的.gif圖檔和imgareaselect-default.css還有scripts資料夾的jquery.imgareaselect.min.js引入專案
以下代碼已整理過,說明都在註解裡
ImgAreaSelectController.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplicationImgAreaSelect.Controllers
{
public class ImgAreaSelectController : Controller
{
//裁剪圖片的View
[HttpGet]
public ActionResult Index()
{
ViewData["openerFieldId"] = Request.QueryString["openerFieldId"];
ViewData["openerSrcId"] = Request.QueryString["openerSrcId"];
return View();
}
/// <summary>
/// 上傳原始檔案
/// </summary>
/// <param name="myFile"></param>
/// <returns></returns>
[HttpPost]
public ActionResult Upload(HttpPostedFileBase myFile, FormCollection form)
{
ModelState.Clear();//上傳檔案無須驗證
//有選擇檔案
if (myFile != null && myFile.ContentLength > 0)
{
//新的檔名
string newName = Guid.NewGuid().ToString() + Path.GetExtension(myFile.FileName);
//暫存圖檔
myFile.SaveAs(Server.MapPath("~/TempFiles/" + newName));
ViewData["sourceImgName"] = newName;
}
ViewData["openerFieldId"] = form["openerFieldId"];
ViewData["openerSrcId"] = form["openerSrcId"];
return View("Index");
}
//裁剪圖片
[HttpPost]
public ActionResult CropImage(FormCollection form)
{
//selection area的左上座標和寬高
int x1 = Convert.ToInt32(form["x1"]);
int y1 = Convert.ToInt32(form["y1"]);
int width = Convert.ToInt32(form["width"]);
int height = Convert.ToInt32(form["height"]);
string sourceImgName = form["sourceImgName"];
string sourceImgPath = Server.MapPath("~/TempFiles/" + sourceImgName);
string targetImgName = Guid.NewGuid().ToString() + ".jpg";
string targetImgPath = Server.MapPath("~/TempFiles/" + targetImgName);
#region 裁剪圖片
//有先做過上傳圖檔
if (!string.IsNullOrEmpty(sourceImgName))
{
//原始圖片
System.Drawing.Image sourceImage = Image.FromFile(sourceImgPath);
//裁剪的區域
Rectangle fromR = new Rectangle(x1, y1, width, height);
//裁剪出來的圖要放在畫布的哪個位置
Rectangle toR = new Rectangle(0, 0, width, height);
//要當畫布的Bitmap物件
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height);
//產生畫布
System.Drawing.Graphics g = Graphics.FromImage(bitmap);
//清空畫布,背景白色
g.Clear(Color.White);
//以像素做為測量單位
GraphicsUnit units = GraphicsUnit.Pixel;
//剪裁
g.DrawImage(sourceImage, toR, fromR, units);
//裁剪完成,存檔
bitmap.Save(targetImgPath, ImageFormat.Jpeg);
//釋放資源
g.Dispose();
bitmap.Dispose();
sourceImage.Dispose();
System.IO.File.Delete(sourceImgPath);//把原始檔刪除
}
#endregion
string js = "<script>" +
"window.opener.document.getElementById('" + form["openerFieldId"] + "').value='" + targetImgName + "';" +
"window.opener.document.getElementById('" + form["openerSrcId"] + "').src='" + Url.Content("~/TempFiles/" + targetImgName) + "';" +
"window.opener=null; " +//關閉子視窗
"window.open('','_self');" +
"window.close();" +
"</script>";
return Content(js);
}
}
}
ImgAreaSelect的View(Index.cshtml)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>裁剪圖片</title>
@*引用jQuery核心函式庫*@
<script src="~/Scripts/jquery-2.0.2.min.js"></script>
@*引用jQuery imageAreaSelect的相關檔案*@
<script src="~/Scripts/jquery.imgareaselect.min.js"></script>
<link href="~/Content/css/imgareaselect-default.css" rel="stylesheet" />
<script type="text/javascript">
$(document).ready(init);
function init() {
//上傳圖片
$("input[name='myFile']").change(function () {
//改變表單post的action
var action = "@Url.Action("Upload","ImgAreaSelect")";
$("form").attr("action", action);
$("form").submit();
});
var sourceImgName = $("input[name='sourceImgName']").val();
//已上傳過圖檔
if (sourceImgName != "") {
//對原始圖檔呼叫 imgAreaSelect()
$('#sourceImage').imgAreaSelect({
resizable: false,//使用者不可縮放selection area
persistent: true,//使用者click selection area之外的地方不會重新開始一個新的selection area
aspectRatio: '1:1', x1: 0, y1: 0, x2: 120, y2: 120,//selection area的寬高比例和預設寬高
onSelectEnd: function (img, selection) { //當使用者拖放結束時,儲存selection area的左上座標和寬高給hidden
$('input[name="x1"]').val(selection.x1);
$('input[name="y1"]').val(selection.y1);
$("input[name='width']").val(selection.width);
$("input[name='height']").val(selection.height);
}
});
}
}
</script>
</head>
<body>
@using (Html.BeginForm("CropImage", "ImgAreaSelect", FormMethod.Post,new {enctype= "multipart/form-data"}))
{
//要裁剪的座標和寬高
@Html.Hidden("x1",0)
@Html.Hidden("y1",0)
@Html.Hidden("width",120)
@Html.Hidden("height",120)
//原始圖檔名稱
@Html.Hidden("sourceImgName", ViewData["sourceImgName"])
//要置換window.opener的欄位
@Html.Hidden("openerFieldId",ViewData["openerFieldId"])
@Html.Hidden("openerSrcId",ViewData["openerSrcId"])
<span>請選擇檔案</span>
<input type="file" name="myFile" />
<hr />
if (ViewData["sourceImgName"]!=null)
{
<span style="color:red;">請選擇要裁剪的區域</span><br />
}
//img必須指定src,有圖的話jQuery Plugin才有效
<img id="sourceImage" src="@Url.Content("~/TempFiles/" + ViewData["sourceImgName"])" />
<br />
<input type="submit" value="確定" />
}
</body>
</html>
一般要使用的話…
HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplicationImgAreaSelect.Controllers
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Form()
{
return View();
}
//儲存
[HttpPost]
public ActionResult Form(FormCollection form)
{
//裁圖檔名
string imageFileName = form["imageFileName"];
//裁圖Url
string imgUrl = Url.Content("~/TempFiles/" + imageFileName);
//裁圖路徑
string imgPath = Server.MapPath("~/TempFiles/" + imageFileName);
//把資料儲存DB或搬移檔案等等,剩下的自行料理....
return View();
}
}
}
HomeController的View(Form.cshtml)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Form</title>
<script src="~/Scripts/jquery-2.0.2.min.js"></script>
<script type="text/javascript">
$(document).ready(init);
function init() {
//註冊button按下後事件,開啟imgAreaSelect頁面
$("#btnOpenImgAreaSelect").click(function () {
//一裁剪完,此頁的圖片要顯示裁剪圖片而hidden欄位要記下裁剪後圖片的檔名
var url = "@Url.Action("Index", "ImgAreaSelect")" + "?" + "openerFieldId=imageFileName" + "&" + "openerSrcId=imgDemo";
window.open(url, '', 'width=1024,height=768');//覺得window.open()太醜的話,再自行用fancybox或colorbox美化
});
}
</script>
</head>
<body>
<div>
@using (Html.BeginForm("Form", "Home", FormMethod.Post, new { @class = "form-horizontal", enctype = "multipart/form-data" }))
{
@Html.Hidden("imageFileName")
<img id="imgDemo" src="">
<br />
<input type="button" id="btnOpenImgAreaSelect" value="另開視窗" />
<br />
<input type="submit" value="儲存" />
}
</div>
</body>
</html>
執行結果:
結語
此Plugin還有一些參數不錯用,可以自行參考官網看看
參考文章: