file - convert - image base64 angular 4
Angular 2 codifica la imagen a base64 (3)
Quiero codificar los archivos cargados en base64 para poder pasarlos a la solicitud. El problema es que estoy usando Angular 2 con Typescript y no pude encontrar información sobre cómo hacerlo. Descubrí que en Javascript se puede hacer con lienzo pero no sé cómo podría implementar el código en Typescript.
<input type="file" class="form-control" accept="image/*" multiple
[(ngModel)]="spot.images" name="images">
Aquí está la respuesta anterior envuelta en un componente reutilizable que se relaciona con ngmodel.
import { NgModule, Component, Input, Output, ElementRef, forwardRef } from ''@angular/core'';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from ''@angular/forms'';
import { FormsModule } from "@angular/forms";
@Component({
selector: ''file-upload'',
template: `<input *ngIf="showFileNameInput" id="uploadFile" class="upload-file form-control" placeholder="Choose File" [(ngModel)]="selectedFileName" disabled="disabled" />
<div class="fileUpload btn btn-primary">
<span>{{uploadButtonText}}</span>
<input type="file" class="upload" accept="*" (change)="changeListener($event)">
</div>`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => FileUploadComponent),
multi: true
}
]
})
export class FileUploadComponent implements ControlValueAccessor {
selectedFileName: string = null;
@Input() showFileNameInput: boolean;
@Input() uploadButtonText: string;
writeValue(value: any) {
//Handle write value
}
propagateChange = (_: any) => { };
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched() { }
changeListener($event): void {
// debugger; // uncomment this for debugging purposes
this.readThis($event.target);
}
readThis(inputValue: any): void {
// debugger; // uncomment this for debugging purposes
var file: File = inputValue.files[0];
var myReader: FileReader = new FileReader();
myReader.onloadend = (e) => {
this.propagateChange(myReader.result);
this.selectedFileName = file.name;
}
myReader.readAsDataURL(file);
}
}
@NgModule({
declarations: [
FileUploadComponent
],
imports: [FormsModule],
exports: [
FileUploadComponent
]
})
export class FileUploadModule { }
Que se puede usar como
<file-upload [showFileNameInput]="true" allowedTypes="image/*" uploadButtonText="Upload File" [(ngModel)]="someProperty"></file-upload>
También algo de css que lo ayudó a mezclarse con el bootstrap en mi sitio
/********************************/
/* File Upload */
.fileUpload {
position: relative;
overflow: hidden;
}
.fileUpload input.upload {
position: absolute;
top: 0;
right: 0;
margin: 0;
padding: 0;
font-size: 20px;
cursor: pointer;
opacity: 0;
filter: alpha(opacity=0);
}
.upload-file {
&.form-control {
width: auto;
display: inherit;
}
}
Entonces encuentro la solución:
compontent.ts
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.image = myReader.result;
}
myReader.readAsDataURL(file);
}
component.html
<input type="file" accept="image/*" (change)="changeListener($event)">
Puedes crear una clase Wrapper para que la clase FileReader devuelva un elemento observable. Suscríbete y, con éxito, utiliza el .target para obtener el base64 y haz lo que quieras.
import {ReplaySubject} from "rxjs/ReplaySubject";
import {Observable} from "rxjs/Observable";
export class ObservableFileReader {
constructor(){}
public readFile(fileToRead: File): Observable<MSBaseReader>{
let base64Observable = new ReplaySubject<MSBaseReader>(1);
let fileReader = new FileReader();
fileReader.onload = event => {
base64Observable.next(fileReader.result);
};
fileReader.readAsDataURL(fileToRead);
return base64Observable;
}
}