簡體   English   中英

如何上傳/ POST多個canvas元素

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM