将图像路径转换为blob反应原生

GII*_*ISE 7 javascript firebase react-native firebase-storage

问题

我正在尝试使用react native和firebase创建一个应用程序.我想要这个应用程序的功能之一是上传图像的能力.我在将图像上传到firebase存储时遇到了一些麻烦.我正在使用expo的图像选择器来查找用户想要上传的图像的路径,但是一旦我有了路径,我就不知道如何将其转换为我可以上传到firebase的内容.

有人可以帮助我将图像的路径转换为我可以使用react native上传到firebase存储的内容吗?

我试过的

我试过用:

     _pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      MediaTypeOptions: 'Images',
      quality: 0.4,
_uploadAsByteArray = async (pickerResultAsByteArray, progressCallback) => {

    try {

      var metadata = {
        contentType: 'image/jpeg',
      };

      var storageRef = firebase.storage().ref();
      var ref = storageRef.child('images/'+expoID+'/'+this.state.time)
      let uploadTask = ref.put(pickerResultAsByteArray, metadata)

      uploadTask.on('state_changed', function (snapshot) {

        progressCallback && progressCallback(snapshot.bytesTransferred / snapshot.totalBytes)

        var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        console.log('Upload is ' + progress + '% done');

      }, function (error) {
        console.log("in _uploadAsByteArray ", error)
      }, function () {
        var downloadURL = uploadTask.snapshot.downloadURL;
        console.log("_uploadAsByteArray ", uploadTask.snapshot.downloadURL)
    this.setState({imageUploaded:true})
      });


    } catch (ee) {
      console.log("when trying to load _uploadAsByteArray ", ee)
    }
  }


  convertToByteArray = (input) => {
    var binary_string = this.atob(input);
    var len = binary_string.length;
    var bytes = new Uint8Array(len);
    for (var i = 0; i < len; i++) {
      bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes
  }

  atob = (input) => {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

    let str = input.replace(/=+$/, '');
    let output = '';

    if (str.length % 4 == 1) {
      throw new Error("'atob' failed: The string to be decoded is not correctly encoded.");
    }
    for (let bc = 0, bs = 0, buffer, i = 0;
      buffer = str.charAt(i++);

      ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
        bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
    ) {
      buffer = chars.indexOf(buffer);
    }

    return output;
  }


uploadImage(bsfdata){
    this.setState({imageUploaded:false})
    this._uploadAsByteArray(this.convertToByteArray(bsfdata), (progress) => {
    this.setState({ progress:progress })
    })
  }
  base64:true,
});



 /* if (!result.cancelled) {
      this.setState({ image: result.uri });
      let formData = new FormData();
        formData.append('photo', {
           uri,
           name: `photo.${fileType}`,
           type: `image/${fileType}`,
     });}*/
      this.uploadImage(result.base64);
  };

}
Run Code Online (Sandbox Code Playgroud)

我已经尝试添加了注释代码,它没有上传任何内容,我已经尝试了代码现在如何,这给了我错误Can currently only create a Blob from other Blobs,上传进度永远不会超过0%.

小智 10

.blob()在本机反应中不起作用!你需要一个函数来完成这个任务

export const uriToBlob = (uri) => {
 return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.onload = function () {
      // return the blob
      resolve(xhr.response)
    }
    xhr.onerror = function () {
      reject(new Error('uriToBlob failed'))
    }
    xhr.responseType = 'blob'
    xhr.open('GET', uri, true)

    xhr.send(null)})}
Run Code Online (Sandbox Code Playgroud)

并将函数上传到firebase:

export async function uploadFile(uri, filename, folder) {
  if (!filename) return
  const storageRef = ref(storage, `${folder}/${filename}`)
  const blobFile = await uriToBlob(uri)
  try {
    uploadBytes(storageRef, blobFile).then(async (snapshot) => {
      console.log('snapshot', snapshot)
      const url = await getDownloadURL(storageRef)
      return url
    })
  } catch (err) {
    console.log(err)
    return null
  }
}
Run Code Online (Sandbox Code Playgroud)


Sri*_*oor 8

如果您使用的是 expo (>=26),那么您可以使用以下代码行轻松完成。

uploadImage = async(imageUri) => {
  const response = await fetch(imageUri);
  const blob = await response.blob();
  var ref =   firebase.storage().ref().child("image.jpg");
  return ref.put(blob);
}
Run Code Online (Sandbox Code Playgroud)

参考:https : //youtu.be/KkZckepfm2Q

  • 有时会无缘无故地出现网络错误。有时它就像一个魅力 (2认同)

K.W*_*.Wu 0

您需要安装rn-fetch-blob模块:

npm install --save rn-fetch-blob
Run Code Online (Sandbox Code Playgroud)

然后,执行以下操作:

import RNFetchBlob from 'rn-fetch-blob';

const Blob = RNFetchBlob.polyfill.Blob;
const fs = RNFetchBlob.fs;
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
window.Blob = Blob;

function uploadImage(path) {
    const imageFile = RNFetchBlob.wrap(path);

    // 'path/to/image' is where you wish to put your image in
    // the database, if you would like to put it in the folder
    // 'subfolder' inside 'mainFolder' and name it 'myImage', just 
    // replace it with 'mainFolder/subfolder/myImage'
    const ref = firebase.storage().ref('path/to/image');
    var uploadBlob = null;

    Blob.build(imageFile, { type: 'image/jpg;' })
        .then((imageBlob) => {
            uploadBlob = imageBlob;
            return ref.put(imageBlob, { contentType: 'image/jpg' });
        })
        .then(() => {
            uploadBlob.close();
            return ref.getDownloadURL();
        })
        .((url) => {
            // do something with the url if you wish to
        })
        .catch(() => {
            dispatch({
                type: UPDATE_PROFILE_INFO_FAIL,
                payload: 'Unable to upload profile picture, please try again'
            });
        });
}
Run Code Online (Sandbox Code Playgroud)

请询问代码中是否有任何您不理解的部分。要上传多个图像,只需用 for 循环包装此代码即可。或者,如果您想确保上传的每个图像都没有任何错误,请使用Promise

  • 仅供参考,对于任何想要将图像上传到 firebase 存储但不使用 expo 的人(就像我不使用 expo 一样),您可以将图像 uri 作为第一个参数传递给 ref.put() 函数。即 ref.put(uri) (2认同)

归档时间:

查看次数:

12563 次

最近记录:

6 年,7 月 前