[英]How to upload/POST multiple canvas elements
我必須為將來的項目(無閃光燈,IE10 +,FF7 +等)創建一個圖像上傳器,它在客戶端而不是服務器上進行圖像大小調整/轉換/裁剪。
所以我創建了一個javascript界面,用戶可以“上傳”他們的文件並直接在瀏覽器中調整大小/裁剪,而無需聯系服務器。 性能還可以,不是那么好,但它確實有效。
endresult是一個canvas元素數組。 用戶可以在調整大小后編輯/裁剪圖像,因此我將它們保留為畫布而不是將它們轉換為jpeg。 (這將使初始表現惡化)
現在這很好用,但我不知道現在將完成的canvas元素實際上傳到服務器的最佳方法是什么。 (在服務器上使用asp.net 4通用處理程序)
我嘗試從包含每個畫布的dataurl的所有元素創建一個json對象。
問題是,當我得到10-40張圖片時,瀏覽器會在創建dataurls時開始凍結,特別是對於大於2兆字節的圖像。
//images = array of UploadImage
for (var i = 0; i < images.length; i++) {
var data = document.getElementById('cv_' + i).toDataURL('image/jpg');
images[i].data = data.substr(data.indexOf('base64') + 7);
}
將它們轉換為json對象(我使用的是json2.js)通常會導致我的瀏覽器崩潰。 (FF7)
我的目標
var UploadImage = function (pFileName, pName, pDescription) {
this.FileName = pFileName;
this.Name = pName;
this.Description = pDescription;
this.data = null;
}
上傳例程
//images = array of UploadImage
for (var i = 0; i < images.length; i++) {
var data = document.getElementById('cv_' + i).toDataURL('image/jpg');
images[i].data = data.substr(data.indexOf('base64') + 7);
}
var xhr, provider;
xhr = jQuery.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function (e) {
console.log(Math.round((e.loaded * 100) / e.total) + '% done');
}, false);
}
provider = function () {
return xhr;
};
var ddd = JSON.stringify(images); //usually crash here
$.ajax({
type: 'POST',
url: 'upload.ashx',
xhr: provider,
dataType: 'json',
success: function (data) {
alert('ajax success: data = ' + data);
},
error: function () {
alert('ajax error');
},
data: ddd
});
將canvas元素發送到服務器的最佳方法是什么?
我應該一次性還是一個一個地發送它們?
逐個上傳文件會更好。 需要更少的內存,只要一個文件准備好上傳,就可以啟動上傳,而不是等待所有文件都准備好。
使用FormData
發送文件。 允許以二進制格式而不是base64編碼上傳文件。
var formData = new FormData;
如果Firefox使用canvas.mozGetAsFile('image.jpg')而不是canvas.toDataUrl()。 允許避免從base64到二進制的不必要的轉換。
var file = canvas.mozGetAsFile('image.jpg');
formData.append(file);
在Chrome中,使用BlobBuilder將base64轉換為blob(請參閱dataURItoBlob
函數
在玩了幾件事之后,我設法自己解決了這個問題。
首先,這會將dataURI轉換為Blob:
//added for quick reference
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
}
從這個問題 ):
var blob = dataURItoBlob(canvas.toDataURL('image/jpg'));
formData.append(blob);
然后發送formData
對象。 我不確定如何在jQuery中做到這一點,但是使用普通的xhr對象就像這樣:
var xhr = new XMLHttpRequest;
xhr.open('POST', 'upload.ashx', false);
xhr.send(formData);
在服務器上,您可以從Files集合中獲取文件:
context.Request.Files[0].SaveAs(...);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.