2011-10-10 12 views
7

मुझे भविष्य की परियोजना (कोई फ़्लैश, आईई 10 +, एफएफ 7 + इत्यादि) के लिए एक छवि अपलोडर बनाना है जो क्लाइंटसाइड पर छवि का आकार बदलना/कनवर्ट करना/क्रॉप करना है, न कि सर्वर पर।एकाधिक कैनवास तत्वों को अपलोड/POST कैसे करें

इसलिए मैंने एक जावास्क्रिप्ट इंटरफ़ेस बनाया जहां उपयोगकर्ता अपनी फ़ाइलों को 'अपलोड' कर सकता है और सर्वर से संपर्क किए बिना सीधे ब्राउज़र में आकार/क्रॉप कर सकता है। प्रदर्शन ठीक है, अच्छा नहीं है, लेकिन यह काम करता है।

एंड्रेसल्ट कैनवास तत्वों की एक सरणी है। उपयोगकर्ता आकार बदलने के बाद छवियों को संपादित/क्रॉप कर सकते हैं, इसलिए मैं उन्हें जेपीईजी में परिवर्तित करने के बजाय कैनवास के रूप में रखता हूं। (जो प्रारंभिक प्रदर्शन को खराब कर देगा)

अब यह ठीक काम करता है, लेकिन मुझे नहीं पता कि वास्तव में सर्वर पर समाप्त कैनवास तत्वों को वास्तव में अपलोड करने का सबसे अच्छा तरीका क्या है। (सर्वर पर एएसपीनेट 4 जेनेरिक हैंडलर का उपयोग करना)

मैंने प्रत्येक कैनवास के डेटाोरल वाले सभी तत्वों से एक जेसन ऑब्जेक्ट बनाने का प्रयास किया है।

समस्या यह है कि, जब मुझे 10-40 चित्र मिलते हैं, तो डेटालेट्स बनाते समय ब्राउज़र फ्रीजिंग शुरू होता है, खासकर 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); 
      } 

उन्हें एक जेसन ऑब्जेक्ट में परिवर्तित करना (मैं 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 
      }); 

सबसे अच्छा तरीका क्या सर्वर के लिए कैनवस तत्वों को भेजने के लिए हो सकता है?

क्या मुझे उन्हें एक-एक करके एक-एक करके भेजना चाहिए?

+2

यह एक बहुत दिलचस्प सवाल है । निश्चित नहीं है कि बिना किसी टिप्पणी के 2 डाउनवॉट्स, +1 –

+1

क्यों दुनिया में यह प्रश्न डाउनवॉट किया गया था? – Pointy

+0

डेटा यूआरएल जेनरेट करें और इसे एक समय में भेजा है। इससे स्मृति उपयोग कम हो जाएगा। यह आपको प्रगति दिखाने में भी सक्षम बनाता है (xhr2 समर्थित नहीं है)। दूसरी उलझन यह है कि सर्वर तर्क थोड़ा आसान होगा और सर्वर पर स्मृति उपयोग कम होगा। – Gerben

उत्तर

5

फ़ाइलों को एक-एक करके अपलोड करना बेहतर है। कम मेमोरी की आवश्यकता होती है और जैसे ही एक फ़ाइल अपलोड करने के लिए तैयार होती है, अपलोड करने के बजाय अपलोड शुरू किया जा सकता है, जबकि सभी फाइलें तैयार की जाएंगी।

फ़ाइलों को भेजने के लिए FormData का उपयोग करें। बेस 64 एन्कोडेड के बजाय बाइनरी प्रारूप में फ़ाइलों को अपलोड करने की अनुमति देता है।

var formData = new FormData; 

फ़ायरफ़ॉक्स canvas.mozGetAsFile ('image.jpg') का उपयोग करते हैं canvas.toDataUrl के बजाय()। बेस 64 से बाइनरी तक अनावश्यक रूपांतरण से बचने की अनुमति दें।

var file = canvas.mozGetAsFile('image.jpg'); 
formData.append(file); 

क्रोम में BlobBuilder का उपयोग ब्लॉब में बेस 64 कन्वर्ट करने के लिए (देखें dataURItoBlob समारोह

स्वीकार किए जाते हैं कुछ चीजें के साथ चारों ओर खेलने के बाद, मैं अपने आप को यह पता लगा लिया।

सबसे पहले, यह एक ब्लॉब करने के लिए एक dataURI में परिवर्तित कर देंगे:

//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}); 
} 

this question से):

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); 

सर्वर पर आप फ़ाइलें संग्रह से फ़ाइलों को प्राप्त कर सकते हैं:

context.Request.Files[0].SaveAs(...); 
+0

यह ठीक काम कर रहा है, धन्यवाद। – elch

संबंधित मुद्दे