如何使用 axios 和 RNFS 通过 Google Drive API 下载图像?

问题描述 投票:0回答:2

我正在尝试使用 Google Drive API 中的

files:get
方法下载图像,并使用 RNFS 将其存储到路径中。目前,我能够得到正确的响应(也使用 Postman 进行了验证),但我不知道如何处理响应以将其保存为 .jpg 文件。

这是我调用 axios 的代码块:

downloadActivityCard: async function (id) {
    try {
      const params = {
        //  fields: 'kind,driveId,mimeType,id,name,teamDriveId,thumbnailLink,webContentLink,modifiedTime',
        alt: 'media',
        responseType: 'arraybuffer',
      };
      const dirPath = MAINDIRECTORY + '/FeaturedActivityCards/' + id;
      const filePath = `${dirPath}/cardImage.jpg`;
      let card = {};

      //check if file exists
      if (await checkFileExists(filePath)) {
        throw new Error('This Activity Card is already downloaded');
      }

      //set up the get URL, then call axios for response
      const downloadUrl =
        DRIVE_API_URLS.SEARCH_FILES +
        '/' +
        id +
        DRIVE_API_URLS.SEARCH_PARAMETERS;

      const response = await axios.get(downloadUrl, { params }).catch(error => {
        console.error('ERROR IN DOWNLOADING ACTIVITY CARD: ' + error);
      });

      card = response.data;
      //make directory for the newly downloaded card, write the card into this path and return
      await makeDirectory(dirPath);
      await writeFile(true, filePath, card);
      return filePath;
    } catch (e) {
      console.log('ERROR IN DOWNLOADING ACTIVITY CARD: ' + e);
    }
  }

和 RNFS.writeFile:

export async function writeFile(isImage, filepath, content) {
  const options = {
    encoding: '',
  };
  if (isImage) {
    options.encoding = 'base64';
  } else {
    options.encoding = 'utf8';
  }
  return RNFS.writeFile(filepath, content, options.encoding)
    .then(success => {
      console.log(`FILE WRITTEN!: ${filepath}`);
    })
    .catch(err => {
      console.log(`RNFS writeFile: ${err.message}`);
    });
}

当我尝试将此响应写入

.jpg
文件时,该文件以正确的名称保存在正确的目录中。

但是,尽管将 RNFS 编码参数更改为“base64”和“二进制”,但我无法打开图像。我还在 GET 调用中尝试了不同的参数,但不出所料,这并没有解决问题。

我处理 GET 响应的方式是否有任何问题,如果是,我如何修改它以保存从 GET 调用收到的图像?

javascript node.js react-native http google-drive-api
2个回答
1
投票

图像文件可能以无法识别的格式保存。在这种情况下,您可能需要将图像数据转换为您的设备可以识别的格式。 下面是一个示例,说明如何使用此模块从 Google Drive API 下载图像并将其保存到应用程序的文件系统中:

import RNFetchBlob, { FileDownload } from 'react-native-fetch-blob';
import FileDownloadModule from '@react-native-community/file-download';
import RNFS from 'rnfs';

export async function downloadImage(imageUrl) {
  try {
    const response = await RNFetchblob.fetch('GET', imageUrl);
    const filePath = '/path/to/image.jpg';
    const fileName = 'image.jpg';
    FileDownloadModule.save(response, filePath, fileName);
  } catch (error) {
    console.error('There was an error while trying to download the image:',error);
  }
}

0
投票

虽然 Molassay Vladimir 的回答是有效的,但我也会在这里添加这个。

使用

arraybuffer
写入文件时,您没有正确处理来自 Google Drive API 的
RNFS.writeFile
响应。

当您使用 responseType: 'arraybuffer' 向 Google Drive API 发出 GET 请求时,响应将是一个包含图像数据原始字节的 ArrayBuffer 对象。为了使用 RNFS.writeFile 将此数据写入文件,您需要将 ArrayBuffer 转换为 base64 编码的字符串,然后您可以使用“base64”编码选项将其写入文件。

这里是你如何做到的:

downloadActivityCard: async function (id) {
  try {
    const params = {
      alt: 'media',
      responseType: 'arraybuffer',
    };
    const dirPath = MAINDIRECTORY + '/FeaturedActivityCards/' + id;
    const filePath = `${dirPath}/cardImage.jpg`;
    let card = {};

    //check if file exists
    if (await checkFileExists(filePath)) {
      throw new Error('This Activity Card is already downloaded');
    }

    //set up the get URL, then call axios for response
    const downloadUrl =
      DRIVE_API_URLS.SEARCH_FILES +
      '/' +
      id +
      DRIVE_API_URLS.SEARCH_PARAMETERS;

    const response = await axios.get(downloadUrl, { params }).catch(error => {
      console.error('ERROR IN DOWNLOADING ACTIVITY CARD: ' + error);
    });

    // convert ArrayBuffer to base64-encoded string
    const base64Image = Buffer.from(response.data, 'binary').toString('base64');

    // write base64-encoded string to file using RNFS.writeFile
    await makeDirectory(dirPath);
    await writeFile(true, filePath, base64Image);
    return filePath;
  } catch (e) {
    console.log('ERROR IN DOWNLOADING ACTIVITY CARD: ' + e);
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.