Binary image loaded from server to image with javascript - javascript

I'm loading a jpeg image from my server in binary format via XMLHttpRequest (I need it that way). It's not base64 encoded.
Is it possible to turn it to an img object with javascript?
Thanks

If the character encoding of the XMLHttpRequest has been set to something that won't change the binary data, or you've set the response type, you can then run .responseText through btoa (putting it in base64 and letting you assign it as a data URI) or access .response for the binary data, respectively.
Assuming your instance is named xhr and you're using the charset method before xhr.send but after xhr.open do
xhr.overrideMimeType("text/plain; charset=x-user-defined");
then when you're 200 OK
var dataURI = 'data:image/jpeg;base64,' + btoa(xhr.responseText);
Which you can then set as a src of an <img>.
Again assuming xhr, this time .response method; between .open and .send,
xhr.responseType = "arraybuffer";
Then at 200 OK
var arrayBufferView = new Uint8Array(xhr.response), // can choose 8, 16 or 32 depending on how you save your images
blob = new Blob([arrayBufferView], {'type': 'image\/jpeg'}),
objectURL = window.URL.createObjectURL(blob);
Which you can then set as a src of an <img>. Example

Related

Save canvas element to file [duplicate]

Having an HTML Form that is submittet via POST (user clicking the
submit button).
Furthermore having an image that is read via Javascript of a canvas
object (getImageData()).
Question:
How to "inject" this image data into the HTML Form, so that it gets uploaded as Content-Type:multipart/form-data and can be processed via the existing PHP Frameworks Data Extraction Logic?
Example from a <input type="file" upload captured with CHrome in a POST request => it should look like this
------WebKitFormBoundaryBBAQ5B4Ax1NgxFmD
Content-Disposition: form-data; name="images"; filename="fooimage.png"
Content-Type: image/png
Problem:
I know how to uploed it in a seperate request (via ajax, seperate from the form). I know how to upload it as base64 Data an process it manually in the form.
But I do not know how to send the Image Data along the exiting Form so that it looks for the PHP Serverside Scripts exactly the same as an image that is send via <input type="file"...
Reason: Symphony (FileUpload Object) checks if a file is uploaded via the POST Form and fails if I manulally instanciate the object with the data.
So the best solution would be (in regards to a lot of other things, like testing, avoiding unnecessary logik), if the data would be passed the same as a regular form upload. How to do this?
Thanks!
You can use a FormData object to get the values of your form, and then append a blob version of your canvas into the FormData.
This blob will be seen as a file by the server.
Unfortunately, all browsers still don't support the native canvas.toBlob() method, and even worth, all implementations are not the same.
All major browsers now support the toBlob method, and you can find a polyfill on mdn for older browsers.
// the function to create and send our FormData
var send = function(form, url, canvas, filename, type, quality, callback) {
canvas.toBlob(function(blob){
var formData = form ? new FormData(form) : new FormData();
formData.append('file', blob, filename);
var xhr = new XMLHttpRequest();
xhr.onload = callback;
xhr.open('POST', url);
xhr.send(formData);
}, type, quality);
};
// How to use it //
var form = document.querySelector('form'), // the form to construct the FormData, can be null or undefined to send only the image
url = 'http://example.com/upload.php', // required, the url where we'll send it
canvas = document.querySelector('canvas'), // required, the canvas to send
filename = (new Date()).getTime() + '.jpg',// required, a filename
type = 'image/jpeg', // optional, the algorithm to encode the canvas. If omitted defaults to 'image/png'
quality = .5, // optional, if the type is set to jpeg, 0-1 parameter that sets the quality of the encoding
callback = function(e) {console.log(this.response);}; // optional, a callback once the xhr finished
send(form, url, canvas, filename, type, quality, callback);
PHP side would then be :
if ( isset( $_FILES["file"] ) ){
$dir = 'some/dir/';
$blob = file_get_contents($_FILES["file"]['tmp_name']);
file_put_contents($dir.$_FILES["file"]["name"], $blob);
}

converting video src to a single-session blob url

Let's say I have a video element on my website:
<video src="/video.mp4" controls="" id="video"></video>
How do I go about protecting the original source file (/video.mp4) by converting it to a single-session Blob URL?
I have seen a few posts stating that it needs to be done with JavaScript, though none of them actually expand on the necessary details explaining how to do it (or where you can find out how).
So, what is the best approach for something like this?
Here is a quick and dirty example. Hope it helps.
Make sure to go over the docs of all of the methods being used and check their browser support. This will not protect your video from being downloadable though.
// Request the video using a new XMLHttpRequest() with the
// responseType set to blob.
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function(){
var reader = new FileReader();
reader.onloadend = function(){
// Pass this string to atob to decode the base-64 encoded string to a string
// representing each byte of binary data.
var byteCharacters = atob(reader.result.slice(reader.result.indexOf(',') + 1));
// Now you can create an array of byte values using charCodeAt and looping
// over the byte string.
var byteNumbers = new Array(byteCharacters.length);
for(var i = 0; i < byteCharacters.length; i++){
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
// Pass the resulting array to Uint8Array to create a typed array of
// 8-bit, unsigned integers.
var byteArray = new Uint8Array(byteNumbers);
// This can then can be passed to the Blob constructor.
var blob = new Blob([byteArray], {type: 'video/ogg'});
// Now that you have a blob, you can pass it to the createObjectURL method.
var url = URL.createObjectURL(blob);
// The resulting URL can be attached to the src attribute of your video.
document.getElementById('video').src = url;
}
// Pass the response to the FileReader using readAsDataURL.
// This will give you a base-64 encoded string representation of the file.
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', 'https://upload.wikimedia.org/wikipedia/commons/c/c0/Roaring_Burps.ogg');
xhr.send();
<video controls="" id="video"></video>
To make the Blob URL, I found this answer. This will load large files much faster than DavidDomain's answer (which took unacceptably long for my case of a >100MB video file). Although, I believe that this will download the whole video into the browser's memory, and embed the data into the DOM, so larger files might still cause other performance issues.
Why do you want to "[protect] the original source files location" of the video? If something finds the video's location and requests the video file, then that file should be served: that's a server's job.
AFAIK it's practically impossible to load a video file without exposing the URL required to obtain that video file. (It should be technically possible to embed it into the DOM server-side, but that would force the entire video to be loaded before the page shows anything, and would be unusable)

How to turn a string of data into an image in Javascript?

I have a URL of an image that when I set the src of an img to, the img changes to the image on the URL.
I want to download this image as a string so I can store it in local storage.
So I get the image data using XMLHttpRequest and this returns data that looks like this:
�T��ǁ�Y�k����De,�GV��<A:V��TɕH'�:A�
a��.e��E�ʓu�|���ʘ�*GN�'��қ��u�� ��c��]�
�.N���RH!�O�m�Aa���Զ�0U #Pɬ��:�շ���
p�;2��Z���H����¯��P�un>�u�uj��+�쨯
��Z��֦DW>U����.U:V�{�&(My��kύO�S�������e��ԃ����w�
1��j2�Ŭo�#����>ɛP���:E�o}\O���r ��Ύ�
ob�P|b��/e�\#����k>��?mr<�ƭ�0~����f����\�i�^���ޟj��ٙI&=��B���N��(�N��C�kO�o3e�az�G
�|�����AO�A�6�2
�H�^�5��$�Ѭ
\��|x�+�0 ͤ,n�|������B����
w4ɞG�Q!�"�yb#�[A��\m)��߂�dA�h�.��6����q�αA0�bO��20*�LVX�<`Rv�W�6�f'hF���V���n`̌v�7�Ν��OI|���Ԙ�uoqk���n����g��a��ӗ>���Ԏt��
I'm not sure what format this data is in. It could be Base64 based on some Google searching but not 100% sure. This is just what I get when I console.log it. The image data string has a length of 109095. The console freezes when I log this string, can't figure out why.
I then try to set the src of the img in javascript like this:
x.src = "data:image/jpg;base64," + imageData;
And it doesn't work.
If you want a dataURI version of your image, the best way is to set the XHR.responseType to "blob", and read the resulted response blob with a FileReader :
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function(){
var reader = new FileReader();
reader.onload = function(){
img.src = this.result;
result.textContent = this.result;
};
reader.readAsDataURL(this.response);
};
xhr.open('GET', 'https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png');
xhr.send();
<img id="img"/>
<p id="result"></p>
Of course, you'll have to make the call to the same origin, or to an open server (such as wikimedia one).
You should convert the image to base64 first.
Try this link
How to convert image into base64 string using javascript

Convert binary value of image content to base64 string

I'm retrieving previously uploaded image binary content. Now I need to convert it back to a downloadable image. Here is the code I used.
var xhr = new XMLHttpRequest();
xhr.open('GET',httpUrl+ url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
alert(this.response);
var responseArray = new Uint8Array(this.response);
alert('VAL' + responseArray.length);
var base64 =btoa(uint8ToString(responseArray));
window.open("data:image/jpeg;base64," + base64) ;
};
xhr.send();
What could be the issue here? a new window opens up but the image is not appearing which means the content is not correct. Also i checked with an online converter (using the base64 string i get) and it also doesn't show the image. So basically my conversion is wrong.

Interpret binary string as image in Python, generated by Javascript native method

var oReq = new XMLHttpRequest();
var reader = new FileReader();
reader.onload = function(e) {
var rawData = reader.result;
oReq.open("POST", '/upload', true);
oReq.send(rawData);
console.log(rawData);
}
reader.readAsBinaryString(postObj);
// postObj is an image who's src is set to a data uri, taken via a webcam.
console.log(rawData) yields ==>
"PNG
IHDRÈÜÇ IDATx^d½idizw"##rϬ}ëîªÞfÃ!%2
ø£üølpµ0ù Q&É©¡,Ú2l²!æSeÃ$Y-ÉÎLïKuí{îáëºófe³§¦*3#Nó¾Ïr?÷³¼úOþÓùÉ tóne¸Øm.»ÙhÐtÃÅQ7<w''³nοg³Y·Èkóãn<Xì§G]·²Ø
ç]·8wÇ\å¨;á5vÁ°Ì»E¾?æ÷ywtÒuó¯ù{>Ïám]ÇëF£Qwt|\ßó5ä³NæÜÇ°^{r¿ùÜÁ|¡;>:êón0âß¼gûã6rm_ëgçõü4[vG¼gaa!?_à5#~³0\èxcß}Â}ú|ÜÓóóÅ!Ï=?â{®ã½ó^í½v'ü×úþÞ/×ñÏ}P®}Â÷ݸ;9f­X¨?[àUÇ|?à^|þáb=çòɸ[æ·¬#7q]>giÜqÓ~#oq´èMdY4í3-.ùÈzÿü̺Íy
7Ľֺؿ\Ü6¯õ:Ü ß·5r-|ºv½½ôú¬w¶ìõáþ<{/íuí{ÞÎÚy¯Gì%kÎ}NfÓÚÞã5ݶÏÞÔr×
ø«Õッk¯õï</ëïçz¬ïso§ÙsƳü5öß»{ÛÝádÌñö ïgÍÿù¿üWÝƹÝøüX7øK?ùó ê¶/!Ë«ÝÂxÔ"
G.²Éxbæ]ñg#úýgé£Þ;¿ThƳ/ùòû(D¿Ã>2Þ-ð³7¯18"P<=ç>GSr±;r\à;³°<6ÎòZNAázndûûtù¼1ÇVGÁ¼^vܼ\3ÚÆu¸9×g]ÉñA V°0óîÍ£TÃY½ïdaM">ÆhÎF9ú¿](3¯¢xeÜõt
¢DÞN¾E¾oÈEy×q®?ÂÀ»z=Bó|,¯JáæzíýÞ¯ÿöï&äM!rϼWóQÛ^ÏÛÖ5÷ܤûåϸÛüûÃkôF©]ß¿óÜ1F¤üNëÍsM¯Qü²úYX:f¯DSßÌõ4D1eTÛûüvÿþlrpÐM'SÇuòµÈïù?øî½>è~â'~¢ü$
How can I interpret this in Python? On the server, this data shows up as:
'...\x7f\xc2\xb4r\xc2\x87\x1c\xc2\xaa\n-\xc2\x9c\xc2\xa6QF\xc2\xac\xc2\xb0tS\xc3\xa4\xc2\xb0;\xc3\x8cisL#\xc3\x98\xc2\x94E\xc3\x94\xc2\xb8Bz\xc3\xb0\xc3\xa9\xc2\xaa#8\xc2\x90\xc3\xbb\xc3\xa5>\xc3\xbaO\xc2\xa8\xc3\x81H\xc3\x91\xc2\xaf:i\xc2\x8a\xc2\x926\xc2\x8b\xc2\x81\xc3\xbc\xc3\xa1Y\xc3\x93\xc2\x9b\xc2\xbat\xc2\x8f\xc3\x9e~\xc2\xa3PH4\x02_\x04\xc2\xbf\xc2\x92\xc2\xb7\xc3\xad\xc2\x8f\xc3\x9e\xc3\xbf\xc2\xb8<\xc2\x91V\xc3\xa0\xc3\x8b\x1f\xc3\x88\xc3\x9f\xc2\xa2>)\x1d\xc3\x94eY=\xc3\x8ct\xc2\xa9+L^7\xc2\xa2I\xc3\x84\xc2\xba\x03\xc3\xb5!1f\xc3\x97\xc3\x81\xc3\xbfD\xc3\x87\xc3\xb7\x06\xc2\xaa\xc3\xafcz\xc3\xad(\xc3\xb5\xc2\xab\xc3\x96\xc3\xb5<\xc3\x8e\xc2\xab\x08\xc3\x81\xc2\x88\x0b\xc3\x8a;\xc3\x8e!v\xc3\x84\xc2\xb1?\xc2\x8bVn\x19t\xc3\x80\xc2\x8bT`:\x1c\xc3\x8b\xc2\x99\xc3\xb2\xc3\x9c\xc3\xbf\x0fCsXi\xc3\xa6z\xc3\xb3l\x00\x00\x00\x00IEND\xc2\xaeB`\xc2\x82'
Writing this to file as a PNG yields an invalid PNG. Any guidance on saving the image would be helpful.
You will need to convert your image's binary representation into Base64 before uploading - this makes it safe to work with when transferring data over HTTP.
When you receive the Base64 encoded image server-side, you can convert it back to binary, and write this to a file.
Client side code:
To convert to Base64, you need to use
fileReader.readAsDataURL( fileObject )
this automatically represents your data in a safe to upload via HTTP format.
Server side code:
import base64
coded_string = '''Q5YACgA...'''
binary = base64.b64decode(coded_string)
# now write binary to file...
open('/path/to/new_file.png', 'wb').write(rawData)
On the browser:
// Client Side:
var xhr = new XMLHttpRequest();
xhr.open('POST', uploadUrl);
xhr.send(base64EncodedItem);
On the server (I am using Flask/Python 2.x)
# Server Side:
import re
import uuid
# Obtain the base64 string
image_string = request.data
image_string = re.search(r'base64,(.*)', image_string).group(1)
# Generate a file name.
# We can assume PNG format in my specific implementation, but you could search
# the image_string variable to detect filetype.
output = open(str(uuid.uuid4()) + '.png', 'wb')
output.write(image_string.decode('base64'))
output.close()
This worked for me. Hope it helps others.

Categories