在Angular 2中将图像转换为base64

18

在angular 2中将图像转换为base64,图像是从本地上传的。目前我正在使用fileLoadedEvent.target.result。问题在于,当我通过REST服务将此base64字符串发送到java时,它无法解码。当我尝试使用在线编码器 - 解码器处理此base64字符串时,也无法看到已解码的图像。我也尝试过使用canvas。结果不正确。有一件事是肯定的,我得到的base64字符串不正确,我是否需要添加任何包?或者在angular 2中是否有特定的方法来将图像编码为base64,就像在angular 1中使用angular-base64-upload包一样。

请查看下面的示例代码

onFileChangeEncodeImageFileAsURL(event:any,imgLogoUpload:any,imageForLogo:any,imageDiv:any)
{
    var filesSelected = imgLogoUpload.files;
    var self = this;
    if (filesSelected.length > 0) {
      var fileToLoad = filesSelected[0]; 

      //Reading Image file, encode and display
       var  reader: FileReader = new FileReader();
       reader.onloadend = function(fileLoadedEvent:any) {

       //SECOND METHO
       var imgSrcData = fileLoadedEvent.target.result; // <--- data: base64 

        var newImage = imageForLogo;
        newImage.src = imgSrcData;
        imageDiv.innerHTML = newImage.outerHTML;

      }
      reader.readAsDataURL(fileToLoad);
    }
}

1
你需要从输入文件控件上传图像到后端吗? - Habeeb
啊,好的,我猜这是一个区域的问题...你使用 innerHtml 进行的更改不是通常在 Angular2 中的做法。 - laser
当你有一个 onloadend 回调函数时,将它放在 zone 里面,这样 Angular2 就会知道视图应该被更新。 - laser
7个回答

47

base64字符串的工作示例

https://plnkr.co/edit/PFfebmnqH0eQR9I92v0G?p=preview

  handleFileSelect(evt){
      var files = evt.target.files;
      var file = files[0];

    if (files && file) {
        var reader = new FileReader();

        reader.onload =this._handleReaderLoaded.bind(this);

        reader.readAsBinaryString(file);
    }
  }



  _handleReaderLoaded(readerEvt) {
     var binaryString = readerEvt.target.result;
            this.base64textString= btoa(binaryString);
            console.log(btoa(binaryString));
    }

这真的很有用。我很好奇 - 我正在将其实现在一个数组中,该数组正在选择文件并迭代对它们进行编码。由于编码器工作时存在轻微延迟,在this.base64textString中存储结果文件会导致时间问题。是否可能使编码器获取文件读取器引用并将编码后的文件返回给调用函数,而不是将其存储在局部变量中? - Stephen R. Smith
对我有用。谢谢。你知道我怎么在将图片发送到服务器之前减小它们的大小吗? - Manu Chadha
这对我也很好用。非常感谢。 - VIKAS KOHLI

7

我对Parth Ghiya的答案进行了一些修改,这样你就可以上传1到多个图像,并且它们都以base64编码的字符串的形式存储在一个数组中

base64textString = [];

onUploadChange(evt: any) {
  const file = evt.target.files[0];

  if (file) {
    const reader = new FileReader();

    reader.onload = this.handleReaderLoaded.bind(this);
    reader.readAsBinaryString(file);
  }
}

handleReaderLoaded(e) {
  this.base64textString.push('data:image/png;base64,' + btoa(e.target.result));
}

HTML文件

<input type="file" (change)="onUploadChange($event)" accept=".png, .jpg, .jpeg, .pdf" />
<img *ngFor="let item of base64textString"  src={{item}} alt="" id="img">

2

对于base64的另一种解决方案可以参考这篇文章: https://dev59.com/G1oV5IYBdhLWcg3wauOP#36281449

在我的情况下,我执行了以下操作:

getImagem(readerEvt, midia){
    //console.log('change no input file', readerEvt);
    let file = readerEvt.target.files[0];
    var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function () {
        //console.log('base64 do arquivo',reader.result);
        midia.binario = btoa(reader.result);
        //console.log('base64 do arquivo codificado',midia.binario);
    };
    reader.onerror = function (error) {
        console.log('Erro ao ler a imagem : ', error);
    };
}

和HTML组件
<input type="file" class="form-control"  (change)="getImagem($event, imagem)">

<img class="img-responsive"  src="{{imagem.binario | decode64 }}" alt="imagem..." style="width: 200px;"/>

为了显示图片,我创建了解码64的管道。
@Pipe({
  name: 'decode64'
})
export class Decode64Pipe implements PipeTransform {
  transform(value: any, args?: any): any {
    let a = '';
    if(value){
       a = atob(value);
    }
    return a;
  }
}

1

你尝试过使用btoa或Crypto.js将图像编码为base64吗?

链接到cryptojs - https://code.google.com/archive/p/crypto-js/

var imgSrcData = window.btoa(fileLoadedEvent.target.result);

或者 var imgSrcData = CryptoJS.enc.Base64.stringify(fileLoadedEvent.target.result);


我也尝试了btoa和crypto,但是它返回的仍然是相同的字符串。 - lakshmi

1

这里是来自 Parth Ghiya 的相同代码,但已用 ES6/TypeScript 格式编写

picture: string;
handleFileSelect(evt){
    const file = evt.target.files[0];
    if (!file) {
        return false;
    }
    const reader = new FileReader();
    
    reader.onload = () => {
        this.picture = reader.result as string;
    };

    console.log(btoa(this.picture));
}

0

0

我已经通过调用带有JSON的HTTP请求的POST方法得出了答案。

1.事件参数来自HTML输入标记。
2.self.imagesrc是一个组件变量,用于存储数据并在头文件中使用它,我们需要将“this”转换为self变量并在读取器的Onload函数中使用它。
3.this.server是我在此组件中使用的API调用服务组件变量。

UploadImages(event) {
    var file = event.target.files[0];
    var reader = new FileReader();
    reader.readAsDataURL(file);
    var self = this;
    reader.onload = function() {
      self.imageSrc = reader.result.toString();
    };

    var image_data = {
      authentication_token: this.UD.getAuth_key ,
      fileToUpload: this.imageSrc,
      attachable_type: "Photo"
    };

    this.server.photo_Upload(image_data).subscribe(response => {
      if (response["success"]) {
        console.log(response);
      } else {
        console.log(response);
      }
    });
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接