acarlon
acarlon

Reputation: 17282

Setting binary data on img

Say I have an <img/>. This img has src='http://somelocation/getmypic'. At some later time, I may want to change the content of the img based on an ajax call that receives binary data. I only know once I have received the data in the ajax callback whether I want to apply it to the image. I might decide not to.

As far as I can tell from the research that I have done, the only way to set binary data on the img is by base64 encoding the binary data and setting the img src to the resultant base 64 encoded string.

My first and main question is: what is the overhead? Doesn't this mean that I have tripled the processing and memory usage for an image download? My ajax callback gets the binary data that has been loaded into memory, then I base 64 encode the binary stream and then (I assume) the browser decodes this stream back to binary? Or am I missing something and it's actually not that bad?

My secondary question is: Why is there no way to set binary data directly into the img without base64encoding? Most UI languages that I have used allow you to load an image into a 'PictureBox' (for example ) from file and also draw in the 'PictureBox'. Why is this not allowed with an img? I am thinking img.binary=bytes which would set src to 'binary' or something like that. It seems this functionality is split between img and canvas, but sometimes you want to do both. I am just wondering if I am missing something in my understanding (e.g. there is some design or implementation benefit in not allowing binary data to be set directly on img).

Thank you.

Upvotes: 3

Views: 1973

Answers (1)

acarlon
acarlon

Reputation: 17282

Well, this is what I came up with. I am not sure what the performance or memory usage is, but it is a lot easier than base64 encoding and it works with the asp.net MVC FileStreamResult. So, I thought that I would post it here in case it helps somebody else:

 var oReq = new XMLHttpRequest();
    oReq.open("post", '/somelocation/getmypic', true );        
    oReq.responseType = "blob";
    oReq.onload = function ( oEvent )
    {
        var blob = oReq.response;
        var imgSrc = URL.createObjectURL( blob );                        
        var $img = $( '<img/>', {                
            "alt": "test image",
            "src": imgSrc
        } ).appendTo( $( '#bb_theImageContainer' ) );
        window.URL.revokeObjectURL( imgSrc );
    };
    oReq.send( null );

The basic idea is that the data is not tampered with and it is received as a blob. A url is constructed for that blob (I think that essentially means that you can use a URL to access that blob in memory). But the good thing is that you can set the img src to this, which is...awesome.

This answer put me on the right track, then this page and this page on mdn. Note supported browsers.

Upvotes: 2

Related Questions