2012-06-18 32 views
21

मैं वर्तमान में एक वेबसॉकेट एप्लिकेशन पर काम कर रहा हूं जो छवियों को सी ++ सर्वर द्वारा भेज रहा है। मैं वहाँ के आसपास विषयों के एक जोड़े को देखा है लेकिन मैं Firefox में इस त्रुटि से छुटकारा पाने के प्रतीत नहीं कर सकते हैं:जावास्क्रिप्ट और websockets का उपयोग कर ब्लॉब से छवि प्रदर्शित करें

छवि भ्रष्ट या छोटा कर दिया: डेटा: image/png, बेस 64, [कुछ डेटा]

socket.onmessage = function(msg) { 
    var blob = msg.data; 

    var reader = new FileReader(); 
    reader.onloadend = function() { 
     var string = reader.result; 
     var buffer = Base64.encode(string); 
     var data = "data:image/png;base64,"+buffer; 

     var image = document.getElementById('image'); 
     image.src = data; 
    }; 
    reader.readAsBinaryString(blob); 
} 

मैं एक लाल डॉट है कि मैं इस विषय पर पाया की छवि का उपयोग कर रहा: https://stackoverflow.com/a/4478878/1464608 और Base64 वर्ग से है

यहाँ जावास्क्रिप्ट कोड मैं अपने ब्लॉब प्रदर्शित करने के लिए उपयोग कर रहा हूँ है यहां: https://stackoverflow.com/a/246813/1464608

लेकिन मुझे प्राप्त बेस 64 परिणाम मेल नहीं खाता है और फ़ायरफ़ॉक्स मुझे छवि को दूषित होने की एक त्रुटि पुनर्प्राप्त करता है।

मुझे पता है कि यह अधिक जानकारी नहीं है लेकिन मेरे पास कोई सुराग नहीं है जहां देखना है:/ कोई भी मदद स्वागत से अधिक है !!

+0

शायद आप अपने एन्कोडिंग/डिकोडिंग विधि को सुनिश्चित करने के लिए कहीं और अपनी एन्कोडेड छवि को डीकोड करने का प्रयास कर सकते हैं सही है। –

+0

'Base64.encode (स्ट्रिंग) 'से' btoa (स्ट्रिंग)' के परिणाम की तुलना करने का प्रयास करें। अधिकांश बेस 64 पुस्तकालय थोड़ा अलग-अलग काम करते हैं जो उच्च मूल्य वाले बाइट्स के लिए 'btoa'; शायद यह तुम्हारा मुद्दा है? – apsillers

+0

मैंने पहले ही बीओएए() का प्रयास किया है और यह वास्तव में एक अलग परिणाम दे रहा है जो अभी भी काम नहीं कर रहा है। – guitio2002

उत्तर

20

मुझे लगता है कि सबसे साफ समाधान बेस 64 एन्कोडर को स्ट्रिंग के बजाय सीधे Uint8Array पर संचालित करने के लिए बदलना होगा।

महत्वपूर्ण: इसके लिए आपको वेब सॉकेट के बाइनरी टाइप को "arraybuffer" पर सेट करने की आवश्यकता होगी।

onmessage विधि इस तरह दिखना चाहिए:

socket.onmessage = function(msg) { 
    var arrayBuffer = msg.data; 
    var bytes = new Uint8Array(arrayBuffer); 

    var image = document.getElementById('image'); 
    image.src = encode(bytes); 
}; 

परिवर्तित एनकोडर तो इस तरह दिखना चाहिए (पर https://stackoverflow.com/a/246813/1464608 आधार पर):

// public method for encoding an Uint8Array to base64 
function encode (input) { 
    var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/="; 
    var output = ""; 
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4; 
    var i = 0; 

    while (i < input.length) { 
     chr1 = input[i++]; 
     chr2 = i < input.length ? input[i++] : Number.NaN; // Not sure if the index 
     chr3 = i < input.length ? input[i++] : Number.NaN; // checks are needed here 

     enc1 = chr1 >> 2; 
     enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 
     enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 
     enc4 = chr3 & 63; 

     if (isNaN(chr2)) { 
      enc3 = enc4 = 64; 
     } else if (isNaN(chr3)) { 
      enc4 = 64; 
     } 
     output += keyStr.charAt(enc1) + keyStr.charAt(enc2) + 
        keyStr.charAt(enc3) + keyStr.charAt(enc4); 
    } 
    return output; 
} 
+2

धन्यवाद। यह वास्तव में एक अच्छा समाधान है। मेरे लिए मुझे बेस 64 एन्कोडिंग जोड़नी है। मेरा रिटर्न टाइप इस तरह दिखता है: "डेटा: छवि/जेपीजी; बेस 64," + आउटपुट; – abanmitra

13

धन्यवाद, यह बहुत अच्छा काम कर रहा है !!

तो मैं समझ मैं अपने अंतिम जावास्क्रिप्ट कोड का हिस्सा चाहते हैं:

var socket = new WebSocket('ws://'+host+':'+port, protocol); 
socket.binaryType = 'arraybuffer'; 

try { 
    socket.onopen = function() { 
     document.getElementById('status').style.backgroundColor = '#40ff40'; 
     document.getElementById('status').textContent = 'Connection opened'; 
    } 

    socket.onmessage = function(msg) { 
     var arrayBuffer = msg.data; 
     var bytes = new Uint8Array(arrayBuffer); 

     var image = document.getElementById('image'); 
     image.src = 'data:image/png;base64,'+encode(bytes); 
    } 

    socket.onclose = function(){ 
     document.getElementById('status').style.backgroundColor = '#ff4040'; 
     document.getElementById('status').textContent = 'Connection closed'; 
    } 
} catch(exception) { 
    alert('Error:'+exception); 
} 

वास्तव में समझ में नहीं आता क्यों ब्लॉब संस्करण तो मुश्किल है, लेकिन यह चाल किया!

+1

समस्या बाइनरी डेटा को एक (वर्ण) स्ट्रिंग में परिवर्तित कर रही है, जो उपयोग किए गए वर्ण एन्कोडिंग के आधार पर अलग-अलग परिणाम प्रदान करती है। यह आईएसओ -885 9 -1 के लिए काम कर सकता है क्योंकि सभी कोड बिंदुओं को संबंधित यूनिकोड कोड बिंदुओं पर मैप करते हैं। यूटीएफ -8 के लिए, शायद समस्याएं होंगी क्योंकि इनपुट में दो या दो से अधिक बाइट एक वर्ण के रूप में डीकोड किए जा सकते हैं, और कुछ बाइट मान अवैध यूटीएफ -8 कोड बिंदु हो सकते हैं। –

+0

मदद के लिए धन्यवाद, बहुत सराहना की :) – guitio2002

12

आप इसे बहुत सरल लिख सकते हैं:

socket.onmessage = function(msg) { 
    var arrayBuffer = msg.data; 
    var bytes = new Uint8Array(arrayBuffer); 
    var blob  = new Blob([bytes.buffer]); 

    var image = document.getElementById('image'); 

    var reader = new FileReader(); 
    reader.onload = function(e) { 
     image.src = e.target.result; 
    }; 
    reader.readAsDataURL(blob); 
}; 
+0

मेरे लिए काम नहीं किया। हालांकि, मैंने 'var बाइट्स ...' और 'var blob ...' लाइनों को हटाए जाने के बाद काम किया और फिर 'reader.readAsDataURL (blob) बदल दिया; '' reader.readAsDataURL (arrayBuffer); '- जो भी है अभी तक सरल – Headcrab

+0

@Headcrab आप किस ब्राउजर का उपयोग करते हैं? –

+0

फ़ायरफ़ॉक्स 48.0.2 और विंडोज़ 10 पर इंटरनेट एक्सप्लोरर 11। उसी ब्राउज़र पर एज ब्राउज़र में न तो आपका और न ही मेरा संस्करण काम करता है। – Headcrab

1

अन्य उत्तर करने के लिए एक अन्य विकल्प

let urlObject; 

socket.onmessage = function(msg) { 
    const arrayBuffer = msg.data; 
    const image = document.getElementById('image'); 

    if (urlObject) { 
     URL.revokeObjectURL(urlObject) // only required if you do that multiple times 
    } 
    urlObject = URL.createObjectURL(new Blob([arrayBuffer])); 

    image.src = urlObject; 

}; 
1

धन्यवाद, मैं WebSocket द्वारा एक jpeg छवि प्राप्त करते हैं और एक नई विंडो में प्रदर्शित करने में कामयाब रहे:

socket.binaryType = "arraybuffer";     
socket.onmessage = function (msg) 
       { var bytes = new Uint8Array(msg.data); 
        var blob = new Blob([bytes.buffer]); 
        window.open(URL.createObjectURL(blob),'Name','resizable=1'); 
       };