如何将base64字符串转换为文件?

时间:2016-07-29 12:17:22

标签: javascript

我使用jquery插件来裁剪图像。该插件将裁剪图像并将其作为base64编码的字符串提供给我。为了将其上传到S3,我需要将其转换为文件并将文件传递给上传功能。我怎样才能做到这一点?我尝试了很多东西,包括使用atob解码字符串。没有工作。

这里是裁剪插件的代码(' croppie'),它为我提供了编码字符串:

imageCropper.croppie('result', {
    type: 'canvas',
    size: 'viewport',
    format: 'jpeg'
}).then(function (resp) {
  updateAvatar(resp);
});

我将它传递给一个名为updateAvatar的函数。这是updateAvatar函数:

updateAvatar({Meteor, Slingshot}, avatar) {
  const uploader = new Slingshot.Upload('userAvatarUpload');

  uploader.send(avatar, function (error, downloadUrl) {
    if (error) {
      // Log service detailed response.
      console.error('Error uploading', uploader.xhr.response);
      console.log(error);
    }
    else {
      console.log('uploaded', downloadUrl);
    }
  });
}

uploader.send函数需要文件或网址。它不接受我编码的字符串。

我用来将文件上传到S3的插件:https://github.com/CulturalMe/meteor-slingshot

2 个答案:

答案 0 :(得分:3)

似乎代码中缺少的“砖块”是一个函数,它将采用base64编码的图像并将其转换为Blob。

所以,我将专注于那一部分,每一步都只有一个简短的评论。

以下函数需要一个字符串,例如:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICA...

function base64ImageToBlob(str) {
  // extract content type and base64 payload from original string
  var pos = str.indexOf(';base64,');
  var type = str.substring(5, pos);
  var b64 = str.substr(pos + 8);

  // decode base64
  var imageContent = atob(b64);

  // create an ArrayBuffer and a view (as unsigned 8-bit)
  var buffer = new ArrayBuffer(imageContent.length);
  var view = new Uint8Array(buffer);

  // fill the view, using the decoded base64
  for(var n = 0; n < imageContent.length; n++) {
    view[n] = imageContent.charCodeAt(n);
  }

  // convert ArrayBuffer to Blob
  var blob = new Blob([buffer], { type: type });

  return blob;
}

答案 1 :(得分:1)

将base64字符串转换为blob,以便在上传到S3时使用。当然,有更简洁的方法可以做到这一点! :)

原创SO答案:https://stackoverflow.com/a/16245768/1350913

  imageCropper.croppie('result', {
  type: 'canvas',
  size: 'viewport',
  format: 'jpeg'
}).then(function(resp) {
  var contentType = 'image/png';
  var s3Blob = b64toBlob(resp, contentType);
  updateAvatar(s3Blob);
});

updateAvatar({
  Meteor,
  Slingshot
}, avatar) {
  const uploader = new Slingshot.Upload('userAvatarUpload');

  uploader.send(avatar, function(error, downloadUrl) {
    if (error) {
      // Log service detailed response.
      console.error('Error uploading', uploader.xhr.response);
      console.log(error);
    } else {
      console.log('uploaded', downloadUrl);
    }
  });
}

function b64toBlob(b64Data, contentType, sliceSize) {
  contentType = contentType || '';
  sliceSize = sliceSize || 512;

  var b64DataString = b64Data.substr(b64Data.indexOf(',') + 1);      
  var byteCharacters = atob(b64DataString);
  var byteArrays = [];

  for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    var slice = byteCharacters.slice(offset, offset + sliceSize);

    var byteNumbers = new Array(slice.length);
    for (var i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    var byteArray = new Uint8Array(byteNumbers);

    byteArrays.push(byteArray);
  }

  var blob = new Blob(byteArrays, {
    type: contentType
  });
  return blob;
}