Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Image or byte data with http

For a web application I need to get my images with an ajax request because we have signature + authentication on our API, so we can't get images using a simple <img src="myapi/example/145"/>

Since we're using angular2, we obviously looked for blob or something like that, but as stated in static_response.d.ts file:

/**
 * Not yet implemented
 */
blob(): any;

So okay, I can't do it for now, I have to wait for thie feature to be implemented.

But problem is I can't wait so I need a hotfix or a little hack to be able to get image data from response and I'll be able to remove my hack and set the blob() method call to be good when it will be implemented.

I tried this:

export class AppComponent {
    constructor(private api:ApiService, private logger:Logger){}
    title = 'Tests api';
    src='http://placekitten.com/500/200'; //this is src attribute of my test image
    onClick(){ //Called when I click on "test" button
        this.api.test().then(res => {
            console.log(res._body);
            var blob = new Blob([new Uint8Array(res._body)],{
                type: res.headers.get("Content-Type")
            });
            var urlCreator = window.URL;
            this.src = urlCreator.createObjectURL(blob);
        });
    }
}

with ApiService.test() method:

test():Promise<any> {
        return this.http.get(this._baseUrl + "myapi/example/145", this.getOptions())
//getOptions() is just creating three custom headers for     
//authentication and CSRF protection using signature
            .toPromise()
            .then(res => {
                    this.logger.debug(res);
                if(res.headers.get("Content-Type").startsWith("image/")){
                    return res;
                }
                return res.json();
            })
            .catch(res => {
                this.logger.error(res);
                return res.json();
            } );
    }

But I don't get any image from it and logging the response data shows a big string which is image data.

Do you have a hack to achieve this?

like image 856
Supamiu Avatar asked Mar 22 '16 11:03

Supamiu


People also ask

How do I get http images?

Right-click the image, then click one of the following depending on your browser: Chrome - Click Copy image address. Firefox - Click Copy Image Location. Microsoft Edge - Click Copy link.

Are images stored in bytes?

Any image is merely a sequence of bytes structured in accordance with whatever underlying format used to represent it, eg color data, layers, dimensions, etc. The significance of any byte(s) you see during debugging is entirely dependent upon the native format of the image, eg PNG, TIFF, JPEG, BMP, etc.

What is image byte array?

Images are binary data - this is easily represented as byte arrays. The image in the sample is stored in the database as a BLOB - not a string or location, that is, it is binary data.

How are images represented in bytes?

whole bytes (24 bits) are used to represent the colour of each pixel. This is split up into one byte for each of the primary colours of light, red, green and blue. This is because computer displays uses these primary colours of light to display all the different colours we see on the screen.


2 Answers

It is not necessary to extend BrowserXhr anymore. (Tested with angular 2.2.1) RequestOptionsArgs now has a property responseType: ResponseContentType which can be set to ResponseContentType.Blob

Using DomSanitizer

import {DomSanitizer} from '@angular/platform-browser';

This example also creates a sanitized url that can be bound to the src property of an <img>

this.http.get(url,  {
                        headers: {'Content-Type': 'image/jpg'},
                        responseType: ResponseContentType.Blob
                    })
        .map(res => {
            return new Blob([res._body], {
                type: res.headers.get("Content-Type")
            });
        })
        .map(blob => {
            var urlCreator = window.URL;
            return  this.sanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob));
        })
like image 52
tschuege Avatar answered Oct 01 '22 21:10

tschuege


Using the new Angular HttpClient is really easy to achieve this. Going off of tschuege's approach, it would be:

return this._http.get('/api/images/' + _id, {responseType: 'blob'}).map(blob => {
  var urlCreator = window.URL;
  return this._sanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob));
})

The key is to set the responseType as 'blob' so that it doesn't attempt to parse it as JSON

like image 37
cuzox Avatar answered Oct 01 '22 22:10

cuzox