[javascript]檔案上傳以及圖片縮圖成指定的解析度範例
檔案上傳的時候,大多還要縮圖,以下是簡易範例:
Html:使用input type=file的fileupload1元件來做上傳,用隱藏欄位AdImage來做調整解析度的圖片的暫存區,用隱藏欄位AdName來當成新上傳檔案的檔案名稱,用div+img來顯示新上傳的圖片或是顯示從db讀出來的圖片(base64字串的圖片)
<div class="row">
@using (Html.BeginForm("Edit", "AdUpdate", FormMethod.Post, new { @class = "form-horizontal", role = "form", id = "PostForm" }))
{
@Html.AntiForgeryToken()
<input type="hidden" id="AdNum" name="AdNum" value="@ViewBag.AdNum">
<input type="hidden" id="AdImage" name="AdImage">
<input type="hidden" id="AdName" name="AdName">
<div class="col-md-12">
<div class="card" style="width:940px;">
<div class="card-body">
<h4>上方廣告圖片:<span id="fileName">@ViewBag.AdName</span></h4>
<div class="row mt-4 mb-3">
<div class="col-md-12">
<div id="photo" class="align-left" style="width:905px;height:160px; background:#ccc;">
<img src="@ViewBag.AdImage" />
</div>
</div>
</div>
<div class="row mt-4 mb-3" id="myTabContent">
<div class="col-md-6">
<div class="alert alert-danger alert-dismissable">
<span style="color: #880000">圖片檔,寬限為905px,高限為160px。</span>
</div>
</div>
</div>
<div class="row mt-4 mb-3">
<div class="col-md-2 col-md-offset-4">
<label class="btn btn-success btn-file">
<i class="fa fa-lg fa-folder-open"></i> <span>選擇檔案</span>
<input type="file" id="fileUpload1" name="fileUpload1" style="display: none;">
</label>
</div>
<div class="col-md-2" id="updateBtn">
<label class="btn btn-warning" onclick="doUpdate('AdImage', 'AdName', 'fileName','PostForm')">
<i class="fa fa-lg fa-upload"></i> <span>上傳</span>
</label>
</div>
<div class="col-md-2">
<label class="btn btn-block" onclick="location.reload()">
<i class="fa fa-lg fa-close"></i> <span>取消</span>
</label>
</div>
</div>
</div>
</div>
</div>
}
</div>
javascript端於document.ready先幫file upload元件加入onchange事件:SetFileUploadOnChangeEvent()
$(document).ready(function () {
//設定file upload的 onchange event
//addEventListener一定要搭配document.getElementById抓物件,用jquery $("#id")的方式抓物件不行
document.getElementById("fileUpload1").addEventListener("change", function () {
SetFileUploadOnChangeEvent(this.id, 'photo', 'AdImage', 'fileName', 905, 160);
}, false);
});
以下是fileupload元件的change事件的function細節:SetFileUploadOnChangeEvent()
會先用imgCheck()檢查使用者上傳的圖片是否為jpg, png, ....
接著會用imgReSize()調整解析度
最後會將縮圖之後的圖片顯示在div+img
//****設定file upload的 onchange event****
//fileUploadId:上傳檔案的元件的id, imageHolderId:載入圖片的div,
//adImageId: base64字串的圖片, labelfileNameId: 顯示圖檔名稱的label的id
//labelfileNameId: 顯示檔案名稱的label的id
//Max_Width: 圖片的寬度, Max_Height:圖片的高度
function SetFileUploadOnChangeEvent(fileUploadId, imageHolderId, adImageId, labelfileNameId,
Max_Width, Max_Height) {
//檢查圖片格式
//alert(fileUploadId);
var errorMsg = imgCheck(fileUploadId);
if (errorMsg.length > 0) {
swal(errorMsg, "", "error");
return;
}
//alert(typeof (FileReader));
//確認有上傳檔案
if (document.getElementById(fileUploadId).files.length != 0) {
var image_holder = $("#" + imageHolderId);
var AdImage = $("#" + adImageId);
var reader = new FileReader();
reader.onload = function (e) {
imgReSize(e.target.result, imageHolderId, AdImage, fileUploadId,
Max_Width, Max_Height, labelfileNameId);
}
image_holder.show();
//alert('image_holder.show()');
var fName = $("#" + fileUploadId)[0].files[0].name;
//alert(fName);
//var fSize = $(this)[0].files[0].size;
$("#" + labelfileNameId).text(fName);
// $("#fileSize").text(Math.round(fSize / 1024));
reader.readAsDataURL($("#" + fileUploadId)[0].files[0]);
} else {
//alert(1000);
alert("This browser does not support FileReader.");
}
//alert(2000);
//});
}
//檢查上傳格式必須為png, jpg, jpeg
function imgCheck(fileUploadId) {
var errMsg = '';
//var ext = $("#fileUpload1").val().split('.').pop().toLowerCase();
var ext = $("#" + fileUploadId).val().split('.').pop().toLowerCase();
if ($.inArray(ext, ['png', 'jpg', 'jpeg']) == -1) {
errMsg = '請上傳正確的圖片格式';
$("#" + fileUploadId).val('');
}
return errMsg;
}
function imgReSize(source, imageHolderId, B64, fileUploadId, Max_Width, Max_Height, labelfileNameId) {
var img = document.createElement("img");
//alert('start resize');
img.src = source;
//影像RESIZE
img.addEventListener('load', function () {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = Max_Width;
var MAX_HEIGHT = Max_Height;
var width = img.width;
var height = img.height;
//檢查圖片大小
if (width != MAX_WIDTH || height != MAX_HEIGHT) {
swal({
title: "圖片不符合格式:" + MAX_WIDTH + " * " + MAX_HEIGHT + " px,確認繼續上傳?",
type: "warning",
showConfirmButton: true,
showCancelButton: true,
confirmButtonText: "Yes",
cancelButtonText: "No",
closeOnConfirm: true,
closeOnCancel: true
}, function (isConfirm) {
if (isConfirm) {
//確定繼續上傳
}
else {
//中止上傳
$("#" + fileUploadId + "").val('');
var image_holder = $("#" + imageHolderId);
image_holder.empty();
$("#" + labelfileNameId).text('');
return;
}
});
}
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
var ctx = canvas.getContext("2d");
var Width = Max_Width;//預設網頁顯示圖片寬度
var exifOrientation = '';
// Check orientation in EXIF metadatas
EXIF.getData(img, function () {
var allMetaData = EXIF.getAllTags(this);
exifOrientation = allMetaData.Orientation;
//val orientation = ExifInterface(file.absolutePath).getAttribute(ExifInterface.TAG_ORIENTATION)
console.log('Exif orientation: ' + exifOrientation);
});
//alert(333);
// set proper canvas dimensions before transform & export
if (jQuery.inArray(exifOrientation, [5, 6, 7, 8]) > -1) {
canvas.width = height;
canvas.height = width;
//動態修改預設網頁顯示圖片寬度,讓高度在框內
Width = Max_Height * (height / width);
} else {
canvas.width = width;
canvas.height = height;
}
// transform context before drawing image
switch (exifOrientation) {
case 2:
ctx.transform(-1, 0, 0, 1, width, 0);
break;
case 3:
ctx.transform(-1, 0, 0, -1, width, height);
break;
case 4:
ctx.transform(1, 0, 0, -1, 0, height);
break;
case 5:
ctx.transform(0, 1, 1, 0, 0, 0);
break;
case 6:
ctx.transform(0, 1, -1, 0, height, 0);
break;
case 7:
ctx.transform(0, -1, -1, 0, height, width);
break;
case 8:
ctx.transform(0, -1, 1, 0, 0, width);
break;
default:
ctx.transform(1, 0, 0, 1, 0, 0);
}
ctx.drawImage(img, 0, 0, width, height);
var dataurl = canvas.toDataURL("image/jpeg", 1);
/*
canvas.toBlob(function (blob) {
$('#reFileSize').text(Math.round(blob.size / 1024));
}, 'image/jpeg', 1);
*/
B64.val(dataurl);
$("#" + imageHolderId).empty();
$("<img />", {
"width": Width,
"src": dataurl
}).appendTo($("#" + imageHolderId));
//alert('fin')
});
}
補充一下如何送出submit然後上傳縮圖之後的照片到db:
利用ajax將base64字串格式的圖片上傳到Db
//更新圖檔
//imgId:base64圖片字串物件的id, hidAdNameId: 檔案名稱隱藏欄位的id, labelfileNameId:檔案名稱的label的id
function doUpdate(imgId, hidAdNameId, labelfileNameId, formId) {
//alert(111);
$("#" + imgId).val($("#" + imgId).val().split(",")[1]);
//alert($("#" + labelfileNameId).text());
//alert(222);
$("#" + hidAdNameId).val($("#" + labelfileNameId).text());
if ($("#" + imgId).val() == '' || $("#" + hidAdNameId).val() == '') {
swal("請上傳圖片!", "", "error");
}
var postUrl = '';
postUrl = "/AdUpdate/Edit";
$.ajax({
type: 'Post',
url: postUrl,
data: $("#" + formId).serialize(),
success: function (data) {
if (data.success) {
swal({
title: '更新成功!',
text: '',
type: 'success'
}, function () {
location.reload();
});
} else {
$(".validation-summary-valid ul").empty();
for (var i = 0; i < data.errors.length; i++) {
var error = data.errors[i];
$(".validation-summary-valid ul").append($("<li>").text(error));
}
}
}
});
}
參考資料:
經驗