Angular 2将图像编码为base64

时间:2016-09-01 13:32:10

标签: file angular typescript base64 encode

我想将上传的文件编码为base64,以便我可以将它们传递给请求。问题是我正在使用带有Typescript的Angular 2,但我找不到任何关于如何做到这一点的信息。我发现在Javascript中它可以用canvas完成,但我不知道如何在Typescript中实现代码。

<input type="file" class="form-control" accept="image/*" multiple
    [(ngModel)]="spot.images" name="images">

4 个答案:

答案 0 :(得分:53)

所以我找到了解决方案:

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

答案 1 :(得分:7)

上面的答案包含在一个可重复使用的组件中,该组件与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 { }

可以像

一样使用
<file-upload [showFileNameInput]="true" allowedTypes="image/*" uploadButtonText="Upload File" [(ngModel)]="someProperty"></file-upload> 

还有一些css帮助它融入了我网站上的bootstrap

/********************************/
/* 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;
    }
}

答案 2 :(得分:3)

您可以为FileReader类创建一个Wrapper类,以便为它返回一个observable.Subscribe,并且在成功时使用.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;
   }
}

答案 3 :(得分:2)

使用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'));
  }