Angular 2 encode image to base64

后端 未结 4 1538
甜味超标
甜味超标 2020-12-24 02:28

I want to encode the uploaded files to base64 so that I can pass them to the request. The problem is that I\'m using Angular 2 with Typescript and I couldn\'t find any info

相关标签:
4条回答
  • 2020-12-24 02:36

    So I find the solution:

    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)">
    
    0 讨论(0)
  • 2020-12-24 02:44

    Here is the answer above wrapped in a reuseable component that ties into 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 { }
    

    Which can be used like

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

    Also some css that helped it blend into bootstrap on my site

    /********************************/
    /* 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;
        }
    }
    
    0 讨论(0)
  • 2020-12-24 02:49

    A possible solution using 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'));
      }
    
    0 讨论(0)
  • 2020-12-24 02:54

    You can create a Wrapper class for the FileReader class to return an observable.Subscribe for it and on success use the .target to get the base64 for do whatever you want.

    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;
       }
    }
    
    0 讨论(0)
提交回复
热议问题