52

I'm trying to show an image get from a remote server with angular 2.

In my component I have an object that is an "university_info" object that is my model.

export class myClass
{
    university_info : university_info;
}
myFunction()
{
    this.university_info = new university_info(responseFromServer[image])
}

export class university_info
{
    imageBase64 : string
    constructor(image : string)
    {
        this.imageBase64 = image
    }
}

All is working fine. I get base64 image but when I try to show it in HTML in this way :

  <img [src]="'data:image/jpg;base64,'+university_info.imageBase64" />

That's is what I get :

enter image description here

enter image description here

enter image description here

Marco Castano
  • 1,114
  • 1
  • 10
  • 25

7 Answers7

105

I feel like this thread lacks concrete examples which made me have some difficulties:

Import DomSanitizer:

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

define in constructor:

constructor(private _sanitizer: DomSanitizer) { }

Sanitize the Base64 string you want to pass as your image source (use trustResourceUrl):

this.imagePath = this._sanitizer.bypassSecurityTrustResourceUrl('data:image/jpg;base64,' 
                 + toReturnImage.base64string);

Bind to html:

<img [src]="imagePath">
DGK
  • 2,947
  • 5
  • 32
  • 47
45

Solution: Just use 'data:image/jpg;base64' into your image tag like this

<img src="{{'data:image/jpg;base64,' + imagePath}}" />
kbpontius
  • 3,867
  • 1
  • 30
  • 34
Rahul Jograna
  • 856
  • 10
  • 9
15

You can try to use _sanitizer.bypassSecurityTrustUrl to tell angular src value is safe. Take a look at this class from angular:

class DomSanitizationService {
    sanitize(context: SecurityContext, value: any) : string
    bypassSecurityTrustHtml(value: string) : SafeHtml
    bypassSecurityTrustStyle(value: string) : SafeStyle
    bypassSecurityTrustScript(value: string) : SafeScript
    bypassSecurityTrustUrl(value: string) : SafeUrl
    bypassSecurityTrustResourceUrl(value: string) : SafeResourceUrl
}

and be low an example for safe html:

export class AppComponent  {

    private _htmlProperty: string = '<input type="text" name="name">';

    public get htmlProperty() : SafeHtml {
       return this._sanitizer.bypassSecurityTrustHtml(this._htmlProperty);
    }

    constructor(private _sanitizer: DomSanitizationService){}
}
Wasif Ali
  • 886
  • 1
  • 13
  • 29
null canvas
  • 10,201
  • 2
  • 15
  • 18
  • Thank you, it works great. this article also explains more in detail how the DomSanitizationService works. https://medium.com/@NetanelBasal/angular-2-security-the-domsanitizer-service-2202c83bd90#.88dtia8xl – Ricardo Huertas Nov 14 '16 at 20:54
12

Please find enclosed a proper example of how to upload an image in Base64 in Angular 2/4 and also its display. the actual base64 string is dumped into the debugger console and of course can be stored in database etc.

import { Component, OnInit } from '@angular/core';
// Base 64 IMage display issues with unsafe image
import { DomSanitizer } from '@angular/platform-browser';

@Component({
  selector: 'app-test',
  template: `
            <h1>Test 001 </h1>

          <div class="form-group">
            <label>Image</label>
            <input type="file" class="form-control" accept="application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint,
            text/plain, application/pdf, image/*" (change)="changeListener($event)">
          </div>

          <img *ngIf="base64Image" [src]="domSanitizer.bypassSecurityTrustUrl(base64Image)" />
    `,
  styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {

  private base64Image: string;

  constructor(private domSanitizer: DomSanitizer) { }

  ngOnInit() {
  }

  changeListener($event): void {
    this.readThis($event.target);
  }

  readThis(inputValue: any): void {
    var file: File = inputValue.files[0];
    var myReader: FileReader = new FileReader();

    myReader.onloadend = (e) => {
      this.base64Image = myReader.result;
      console.log(this.base64Image);
    }
    myReader.readAsDataURL(file);
  }

}
Bhail
  • 710
  • 8
  • 14
9

You have to make sure that university_info.imageBase64 is a string type then you code will work.

DEMO : http://plnkr.co/edit/pI35tx9gXZFO1sXj9Obm?p=preview

import {Component,ViewChild,Renderer,ElementRef,ContentChildren} from '@angular/core';

@Component({
  selector: 'my-app',

  template:   `
  <img [src]="'data:image/jpg;base64,'+imagePath"/> 
  `

})
export class App {
  imagePath:string="iVBORw0KG...";
}
micronyks
  • 54,797
  • 15
  • 112
  • 146
3

I would like to propose an alternative solution that builds on the one provided by @gatapia.

The proposed solution is to use the @ViewChild decorator tag (see docs here https://angular.io/docs/ts/latest/api/core/index/ViewChild-decorator.html), to retrieve the element reference within the component, and set the value directly as illustrated in the code snippet below. Important to note that the element being referenced via the ViewChild should be bound with to a local variable using the #, as illustrated in the code snipped below.

Also as the ElementRef docs explains, using the ElementRef directly still exposes risk of XSS also present when using DomSanitizer.

@Component({
  template: `
    <div>
      <img #imgRef> // Note that the #imgRef reference is required to be identified by Angular
    </div>
  `,
})
export class MyComponent implements OnInit {
  src:string;
  @ViewChild('imgRef') img:ElementRef;

  constructor() {
    // In your case, this will be resolved from the server
    this.src = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo=';
  }

  ngOnInit() {
    // Sets the value of the element
    this.img.nativeElement.src = this.src;
  }
}

The following plunkr provides a working code snippet of the above https://plnkr.co/edit/JXf25Pv8LqrFLhrw2Eum?p=preview

JeanPaul A.
  • 3,613
  • 1
  • 20
  • 29
  • this is a perfect response with out too much hassle, only thing I had to adapt was doing this on ngAfterViewChecked to wait for the information to be there. – Fabian Rios May 14 '20 at 08:51
  • The important thing to know, though, is that Angular's DOM security is there for a very good reason. Given that most UI engineers are not actually as well-versed in XSS or other types of attacks as they could be (that's not a dis, just the truth), we shouldn't be trying to squirm around the protections they have built in. Use the dom sanitizer provided by angular for this exact reason. The example provided here is a direct, gaping security hole, which is easily mitigated by using the tools provided by the Angular library for free (and, ironically, with less code) – dudewad Aug 08 '22 at 17:04
2

This question gets high google ranking so I thought I'd put my findings here. Using data binding to set the [src] property of an image can be problematic especially on some older mobile devices. So if you have performance issues with the sanitizer+binding approach you will have to set the src property using the DOM directly:

constructor(private el: ElementRef) {}

...

public imageChanged(base64: string) {
  const im: HTMLImageElement = this.el.nativeElement.querySelector('#imgid'); 
  im.src = data;
}

This may be ugly but its lightning fast.

gatapia
  • 3,574
  • 4
  • 40
  • 48