Angular 2 将图像编码为 base64

Posted

技术标签:

【中文标题】Angular 2 将图像编码为 base64【英文标题】:Angular 2 encode image to base64 【发布时间】:2017-01-09 10:09:15 【问题描述】:

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

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

【问题讨论】:

有什么理由不使用 FileReader.readAsDataURL()? 任何解决方案?我也需要这个 工作代码:stackblitz.com/edit/… 【参考方案1】:

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

【讨论】:

你能添加一个代码sn-p吗?我不明白这里的想法【参考方案2】:

所以我找到了解决方案:

组件.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)">

【讨论】:

这非常有效。我什至可以将它包装在与 ngmodel 相关联的组件中,以将其用作表单控件。有兴趣可以看我的回答。 美好的一天!在多个文件中怎么样? 太棒了!我使用您的解决方案创建了 StackBlitz:stackblitz.com/edit/encode-base64-img 我收到一个错误 ReferenceError: e is not defined【参考方案3】:

这是上面的答案,包含在与 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 帮助它融入了我网站上的引导程序

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

【讨论】:

如何将其传递给请求?这里的 base64 值是多少? @MixAustria base64 值正在输出到绑定到组件的 ngModel 或 formControl 的任何内容。你可以像这样使用它 Base 64字符串将位于组件的“someProperty”中 您的意思是someProperty 是组件内部的变量吗?很抱歉,我真的很陌生。 @MixAustria 是的 someProperty 是您组件中的一个变量。 @Josh 我在表单中使用 this 时遇到此错误,如果在表单标记中使用 ngModel,则必须设置名称属性或必须将表单控件定义为“独立” ngModelOptions,如何在表单中使用它以便可以通过服务发布【参考方案4】:

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

【讨论】:

以上是关于Angular 2 将图像编码为 base64的主要内容,如果未能解决你的问题,请参考以下文章

将 Base64 编码图像加密为另一个有效的 Base64 编码图像

base 64 以角度编码和解码字符串 (2+)

将 Base64 编码的图像写入文件

python:将base64编码的png图像转换为jpg

Android将base64编码的字符串转换为图像视图

将base 64编码字符串转换为图像