如何上传/发布多个画布元素
我必须为未来的项目(无 Flash、IE10+、FF7+ 等)创建一个图像上传器,它在客户端而不是在服务器上调整图像大小/转换/裁剪。
因此,我制作了一个 JavaScript 界面,用户可以在其中“上传”他们的文件并直接在浏览器中调整大小/裁剪,而无需联系服务器。性能还可以,不是那么好,但是可以用。
最终结果是画布元素的数组。用户可以在调整大小后编辑/裁剪图像,因此我将它们保留为画布,而不是将它们转换为 jpeg。 (这会恶化初始性能)
现在这工作正常,但我不知道现在将完成的画布元素实际上传到服务器的最佳方法是什么。 (在服务器上使用 asp.net 4 通用处理程序)
我尝试从包含每个画布的 dataurl 的所有元素创建一个 json 对象。
问题是,当我获得 10-40 张图片时,浏览器在创建 dataurl 时开始冻结,尤其是对于大于 2 MB 的图像。
//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
});
将画布元素发送到服务器的最佳方式是什么?
我应该一次全部发送还是一张一张发送?
I have to create an image uploader for a future project (No flash, IE10+, FF7+ etc.) that does image resizing/converting/cropping on the clientside and not on the server.
So I made a javascript interface where the user can 'upload' their files and get resized/cropped in the browser directly, without ever contacting the server. The performance is OK, not that good, but it works.
The endresult is an array of canvas elements. The user can edit/crop the images after they got resized, so I keep them as canvas instead of converting them to jpeg. (Which would worsen the initial performance)
Now this works fine, but I don't know what's the best way to actually upload the finished canvas elements to the server now. (Using a asp.net 4 generic handler on the server)
I have tried creating a json object from all elements containing the dataurl of each canvas.
The problem is, when I got 10-40 pictures, the browser starts freezing when creating the dataurls, especially for images that are larger than 2 megabyte.
//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);
}
Also converting them to a json object (I am using json2.js) usually crashes my browser. (FF7)
My object
var UploadImage = function (pFileName, pName, pDescription) {
this.FileName = pFileName;
this.Name = pName;
this.Description = pDescription;
this.data = null;
}
The upload routine
//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
});
What would be the best way to send the canvas elements to the server?
Should I send them all at once or one by one?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
文件一一上传效果更好。需要更少的内存,一旦一个文件准备好上传,就可以开始上传,而不是等待所有文件都准备好。
使用
FormData
发送文件。允许以二进制格式而不是 base64 编码上传文件。如果 Firefox 使用 canvas.mozGetAsFile('image.jpg') 而不是 canvas.toDataUrl()。允许避免从 Base64 到二进制的不必要的转换。
在 Chrome 中,使用 BlobBuilder 将 base64 转换为 blob(请参阅
接受的
dataURItoBlob
函数)在尝试了一些事情之后,我自己设法解决了这个问题。
首先,这会将 dataURI 转换为 Blob:
来自 这个问题):
然后发送
formData
对象。我不知道如何在 jQuery 中执行此操作,但使用普通的 xhr 对象,如下所示:在服务器上,您可以从文件集合中获取文件:
Uploading files one by one is better. Requires less memory and as soon as one file ready to upload, the upload can be started instead of waiting while all files will be prepared.
Use
FormData
to send files. Allows to upload files in binary format instead of base64 encoded.If Firefox use canvas.mozGetAsFile('image.jpg') instead of canvas.toDataUrl(). Allow to avoid unnecessary conversion from base64 to binary.
In Chrome use BlobBuilder to convert base64 into blob (see
dataURItoBlob
functionaccepted
After playing around with a few things, I managed to figure this out myself.
First of all, this will convert a dataURI to a Blob:
From this question):
And then send the
formData
object. I'm not sure how to do it in jQuery, but with plain xhr object it like so:On server you can get files from Files collection: