用MVC實作圖片上傳以及裁圖功能(下)
接續上一篇完成圖片上傳之後,但其實只完成了一半
因為圖片是存在暫存資料夾,而且資料也還沒進到資料庫
先講一下新增的流程好了
選擇圖片-->圖片存到暫存資料夾-->秀出預覽圖-->裁圖-->確定新增-
->將圖檔從暫存資料夾copy至指定資料夾並裁圖-->資料(圖檔路徑)存到資料庫
因此接下來開始寫裁圖的程式
也是推薦一個好套件 Jcrop
其實這套件不是負責裁圖的,他只是一個jQuery搭配Css,讓我們可以拖拉出裁切框框
再將框框的左上角座標跟寬、高,傳到後端利用GDI+做裁圖
一樣先把該匯的js跟css匯入
用法很簡單,在img 上加個id,然後$("#id").Jcrop(….設定...)就行了
在上篇中,圖檔上傳完成後,會執行一個function
我就在此function中將Jcrop的語法加上去,再貼一次上篇的function
function UploadImageSuccess(file, serverData) {
var retVal = eval('(' + serverData + ')');
if (retVal.status == '1') {
$('#上傳狀態').html('上傳成功:' + file.name);
$('#picName').val(retVal.imgSrc);
$('#tmp_img').attr('src', retVal.imgSrc).show();
//下面是裁圖的jQuery========
$('#tmp_img').Jcrop({
setSelect: [0, 0, 250, 250],
onSelect: updateCoords
});
//===========================
}
else {
$('#上傳狀態').html('上傳失敗!');
}
}
我只設定了setSelect ,代表初始的框框大小及位置
與onSelect,代表選取時去執行updateCoords這個function
下面貼完整的View出來
<script type="text/javascript">
//選取時執行的function
function updateCoords(c) {
jQuery('#X').text(c.x);
jQuery('#Y').text(c.y);
jQuery('#W').text(c.w);
jQuery('#H').text(c.h);
jQuery('#picX').val(c.x);
jQuery('#picY').val(c.y);
jQuery('#picW').val(c.w);
jQuery('#picH').val(c.h);
};
</script>
<h2>Create</h2>
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%= Html.LabelFor(model => model.姓名) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.姓名) %>
<%= Html.ValidationMessageFor(model => model.姓名) %>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.性別) %>
</div>
<div class="editor-field">
<%=Html.RadioButton("性別",true,new{id="男"}) %><label for="男">男</label>
<%=Html.RadioButton("性別",false,new{id="女"}) %><label for="女">女</label>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.照片) %><br />
<%-- 顯示出目前框框的左上角座標及寬高--%>
X:<div id="X"></div>
Y:<div id="Y"></div>
寬:<div id="W"></div>
高:<div id="H"></div><br /><br />
<%=Html.UploadImage() %>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<%--隱藏欄位,要傳左上角座標及寬高到後端--%>
<input type="hidden" id="picX" name="picX"/>
<input type="hidden" id="picY" name="picY"/>
<input type="hidden" id="picW" name="picW"/>
<input type="hidden" id="picH" name="picH"/>
<% } %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
加上上方的程式碼後,在圖片上傳完後,就可以看到下面的效果
可以自由的調整框框大小。上方也會顯示出現在的位置及寬高
終於到最後一步,新增該筆資料啦,將資料打完,圖片上傳好後
按下Create,在後端寫好對應的Action如下
[HttpPost]
public ActionResult Create(SWFandCrop data, string picName, int picX, int picY, int picW, int picH)
{
//利用路徑開啟這個圖檔
System.Drawing.Image image = Bitmap.FromFile(Server.MapPath("~") + picName);
//下面就是裁圖的程式,短短幾行
Bitmap bmp = new Bitmap(picW, picH, image.PixelFormat);
Graphics g = Graphics.FromImage(bmp);
g.DrawImage(image, new Rectangle(0, 0, picW, picH),
new Rectangle(picX, picY, picW, picH),
GraphicsUnit.Pixel);
//設定要將圖檔存到哪個路徑下
string path = Server.MapPath("~/UploadImage");
//如果資料夾不存在就新增此資料夾
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
//將圖片存檔並釋放資源
bmp.Save(Path.Combine(path, Path.GetFileName(picName)), image.RawFormat);
bmp.Dispose();
image.Dispose();
//將圖檔的路徑及其他欄位資料存到資料庫
data.照片 = "/UploadImage/"+Path.GetFileName(picName);
data.ID = Guid.NewGuid();
_SWFandCropRepository.InsertSWFandCrop(data);
try
{
_SWFandCropRepository.Save();
}
catch { }
return RedirectToAction("Index");
}
這樣就全部大功告成了。
按下Create後,返回首頁,就可以看到裁好的圖了
性別欄位我忘了將False對應成女生了,不過這不是重點,所以就不做了。
整個上傳到裁圖就完成了!!
這個範例不太好懂,我玩套件玩了兩天,再花了一天組合起來
寫這個範例跟文章又花了四個小時。不過滿好用的,學會以後
以後遇到圖片上傳或裁圖都不用怕啦。
有時候間可以再把程式碼包的漂亮、彈性一點。