BASE64 to image angular 2

2020-01-26 09:30发布

问题:

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 :

回答1:

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){}
}


回答2:

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">


回答3:

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

<img src="{{'data:image/jpg;base64,' + imagePath}}" />


回答4:

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);
  }

}


回答5:

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...";
}


回答6:

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



回答7:

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.