将文件输入 FileReader base64 结果动态分配给 IMG SRC

Assigning File Input FileReader base64 result to IMG SRC dynamically

希望有人能教我一些新知识,我会尽量保持简短,因为我敢打赌这只是我希望遗漏的一些无聊的细节...

我从这样的图像开始,其中 currentImage 是一个现有的图像路径,首先作为默认路径;

<img src="{{currentImage}}">
<input type="file" (click)="onUpload($event)">

然后触发一个基本方法来获取 event.files 等;

onUpload(event) {

      const file: File = event.files[0],
          reader: FileReader = new FileReader(),
           that = this; // *** WORTH NOTING...

      reader.addEventListener('loadend', function () {
        console.log('the resulting base64 string = ', reader.result);
        that.currentImage = reader.result;
      }, false);

      if (file) {
        reader.readAsDataURL(file);
      }

      console.log('does the blob get updated to currentimage?',
                   this.currentImage); // THIS RETURNS THE OLD IMAGE PATH***

  }

这种工作方式,我在控制台中看到了我想要的 base64 字符串,我看到 currentImage var 字符串更新为 html 绑定中的 base64 字符串 {{currentImage}},我看到 img 元素闪烁了新更新的图像...但它立即恢复为最初分配给 currentImage 的默认图像,即使 currentImage 仍然具有新的 base64 字符串.... this.currentImage 的最后一个 console.log 显示原始文件路径。

我一生都无法弄清楚为什么,但我是 FileReader、Angular 等 Web 方面的新手。所以希望有人能为我提供一小块不起眼的馅饼?? :)

PS - 如果重要,那就是 angular 5

控制台日志中的

this.currentImage先执行,reader中的console.log后执行。 你只是绑定事件然后告诉浏览器加载,同时浏览器加载图像并触发事件,最后的console.log已经执行了。

更多代码或实例将有助于找出图像在首次加载后消失的原因。

您必须将 (click) 更改为 (change) 方法

html

<img src="{{currentImage}}">
<input type="file" (change)="onUpload($event)">

打字稿

currentImage = "";


public onUpload(event){
    let reader = new FileReader();
    reader.addEventListener("load", (ev)=>{
        this.currentImage  = ev.target['result']
    });
    reader.readAsDataURL(event.target.files[0]);
}

希望对您有所帮助。

工作演示:https://stackblitz.com/edit/angular-z774jn?file=app%2Fapp.component.ts

(click) 事件绑定替换为 html

中的 (change)
<img [src]="currentImage">
<input type="file" (change)="onUpload($event)">

并在 ts 中传递 e 内部 addEventListener 回调

 onUpload(e) {
    const file: File = e.dataTransfer ? e.dataTransfer.files[0] : e.target.files[0],
    reader: FileReader = new FileReader(),
    that = this; // *** WORTH NOTING...
    reader.addEventListener('load', function (e) {
      console.log('the resulting base64 string = ', e.target.result);
      that.currentImage = e.target.result;
    }, false);
    if (file) {
      reader.readAsDataURL(file);
    }
    console.log('does the blob get updated to currentimage?',
    this.currentImage); // THIS RETURNS THE OLD IMAGE PATH***
 }

(click) 更改为 (change) 并使用以下代码段。

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Angular 5';
 currentImage ;
  onUpload(event) {
    if (event.target.files && event.target.files[0]) {
      const reader = new FileReader();
      reader.onload = (rdr) => {
        this.currentImage = reader.result;
      };
      reader.readAsDataURL(event.target.files[0])
    }
  }
}

WORKING DEMO

所以我需要为睡眠不足的问题道歉。我忽略了这样一个事实,即还涉及一些高级图像处理,base64 需要相应地与之交互,而 属性 绑定的速度不够快,无法赶上下一步。就我而言,您的所有答案都是正确的,而且我一开始只是问了这个问题。所以我是罪魁祸首,在睡了一会之后,我很快就在一个不相关的区域找到了罪魁祸首。非常感谢您抽出时间,我会尽快删除问题。干杯!