File 角度2将图像编码到base64
我想将上传的文件编码到base64,以便将它们传递给请求。问题是,我正在使用Angular 2和Typescript,但我找不到任何关于如何做到这一点的信息。我发现在Javascript中可以用canvas完成,但我不知道如何用Typescript实现代码File 角度2将图像编码到base64,file,angular,typescript,base64,encode,File,Angular,Typescript,Base64,Encode,我想将上传的文件编码到base64,以便将它们传递给请求。问题是,我正在使用Angular 2和Typescript,但我找不到任何关于如何做到这一点的信息。我发现在Javascript中可以用canvas完成,但我不知道如何用Typescript实现代码 <input type="file" class="form-control" accept="image/*" multiple [(ngModel)]="spot.images" name="images"> 您可以
<input type="file" class="form-control" accept="image/*" multiple
[(ngModel)]="spot.images" name="images">
您可以为FileReader类创建一个包装类,以返回一个可观察的。订阅它,成功后使用.target获取base64,以便执行任何您想要的操作
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;
}
}
从“rxjs/ReplaySubject”导入{ReplaySubject};
从“rxjs/Observable”导入{Observable};
导出类ObservableFileReader{
构造函数(){}
公共读取文件(fileToRead:File):可观察{
设base64Observable=新的ReplaySubject(1);
让fileReader=newFileReader();
fileReader.onload=事件=>{
base64Observable.next(fileReader.result);
};
fileReader.readAsDataURL(fileToRead);
可观察的返回基线;
}
}
因此我找到了解决方案:
成分ts
component.html
以上答案被包装在与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 { }
使用Rxjs的可能解决方案
import { fromEvent } from 'rxjs';
import { pluck } from 'rxjs/operators';
onUploadImage(event) {
if (event.target.files.length > 0) {
const fileReader = new FileReader();
let imageToUpload = event.target.files.item(0);
this.imageToBase64(fileReader, imageToUpload)
.subscribe(base64image => {
// do something with base64 image..
});
}
}
imageToBase64(fileReader: FileReader, fileToRead: File): Observable<string> {
fileReader.readAsDataURL(fileToRead);
return fromEvent(fileReader, 'load').pipe(pluck('currentTarget', 'result'));
}
从'rxjs'导入{fromEvent};
从“rxjs/operators”导入{pull};
onUploadImage(事件){
如果(event.target.files.length>0){
const fileReader=new fileReader();
让imageToUpload=event.target.files.item(0);
this.imageToBase64(文件阅读器,imageToUpload)
.订阅(base64image=>{
//使用base64映像执行某些操作。。
});
}
}
imageToBase64(文件读取器:文件读取器,文件读取器:文件):可观察{
fileReader.readAsDataURL(fileToRead);
从事件(fileReader,'load').pipe(pull('currentTarget','result'))返回;
}
您不使用FileReader.readAsDataURL()的任何原因?有解决方案吗?我需要这个工作代码:你能添加一个代码片段吗?我不明白这里的意思,这很好用。我甚至能够将它封装在一个组件中,该组件与ngmodel绑定,将其用作表单控件。如果你感兴趣,请看我的答案。祝你愉快!多个文件怎么样?太棒了!我用您的解决方案创建了一个StackBlitz:我收到一个错误引用错误:e未定义您如何将其传递给请求?这里的base64值是什么?@mix64值被输出到绑定到组件的ngModel或formControl的任何对象。您可以这样使用它。基64字符串将位于组件的“someProperty”中。您的意思是someProperty
是组件内部的变量吗?很抱歉,我对这一点很陌生。@是的,someProperty是组件中的一个变量。@Josh我在表单中使用它时遇到此错误,如果在表单标记中使用ngModel,则必须在ngModelOptions中设置name属性或将表单控件定义为“standalone”,如何在表单中使用它,以便可以在服务器上发布
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 { }
<file-upload [showFileNameInput]="true" allowedTypes="image/*" uploadButtonText="Upload File" [(ngModel)]="someProperty"></file-upload>
/********************************/
/* 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;
}
}
import { fromEvent } from 'rxjs';
import { pluck } from 'rxjs/operators';
onUploadImage(event) {
if (event.target.files.length > 0) {
const fileReader = new FileReader();
let imageToUpload = event.target.files.item(0);
this.imageToBase64(fileReader, imageToUpload)
.subscribe(base64image => {
// do something with base64 image..
});
}
}
imageToBase64(fileReader: FileReader, fileToRead: File): Observable<string> {
fileReader.readAsDataURL(fileToRead);
return fromEvent(fileReader, 'load').pipe(pluck('currentTarget', 'result'));
}