React Native将base64图像保存到相册

17

第三方API返回一个base64编码的“QR码图像”,
我需要将该图像保存到用户的相册中。

由于React-Native-Fetch-Blob维护者失踪,所以没有人回答Github问题, 根据React-Native-Fetch-Blob文档中的createFile未按预期工作(未将图像保存到相册中)。

  import fetch_blob from 'react-native-fetch-blob';

  // json.qr variable are return from API

  const fs = fetch_blob.fs
  const base64 = fetch_blob.base64
  const dirs = fetch_blob.fs.dirs

  const file_path = dirs.DCIMDir + "/some.jpg"
  const base64_img = base64.encode(json.qr)

  fs.createFile(file_path, base64_img, 'base64')
  .then((rep) => { 
    alert(JSON.stringify(rep));
  })
  .catch((error) => {
    alert(JSON.stringify(error));
  });

有人以前遇到过这个问题吗?

如何将base64编码的图像字符串保存到用户相册中?(作为jpg或png文件)

由于我使用没有CORS标头的API进行了fetch
我无法在Debug JS Remotely中对其进行调试
Chrome会阻止该请求的发生

我必须在我的Android手机上运行它才能使其正常工作
(真实手机上没有CORS控制)

我计划使用剪贴板保存base64字符串,并硬编码在我的代码中
来调试react-native-fetch-blobcreateFile API出了什么问题


1
顺便说一下,只是一个简单的更新:我放弃了 React Native。我用RN 0.46和RN 0.52构建了两个应用程序。对于简单的应用程序来说还可以,但如果是严肃的创业应用程序。你会筹集资金并雇用人员,并期望它不断改进。不要使用RN。原因:编写接口很容易。是的。但问题在于第三方库和调试。你会在这两个方面浪费很多时间。 - NamNamNam
我记得在2017年RN的版本是0.52或类似的数字。现在是2019年4月29日,最新版本是0.59。我认为RN会逐渐消失。别误解我的意思,我很钦佩那些愿意尝试的人。但不幸的是,RN失败了。 - NamNamNam
Flutter现在很热门(2019年),但因为我现在不需要开发应用程序,所以我没有尝试过。我希望他们能成功。 - NamNamNam
6个回答

28

去除你的base64字符串中的data:image/png;base64,

var Base64Code = base64Image.split("data:image/png;base64,"); //base64Image is my image base64 string

const dirs = RNFetchBlob.fs.dirs;

var path = dirs.DCIMDir + "/image.png";

RNFetchBlob.fs.writeFile(path, Base64Code[1], 'base64')
.then((res) => {console.log("File : ", res)});

然后我解决了我的问题。


你救了我的一天。我一直在写文件时加上“data:image/png;base64”字符串。而你的答案刚好帮我解决了这个问题。非常感谢你。 - Rashmi
非常感谢!你救了我的一天! - Viet Nguyen Trong

8
我解决了这个问题,原来我忘记在字符串开头加上data:image/png;base64,
图片描述 我使用以下代码将其删除:
  // json.qr is base64 string
  var image_data = json.qr.split('data:image/png;base64,');
  image_data = image_data[1];

然后保存图像文件。

  import fetch_blob from 'react-native-fetch-blob';
  import RNFS from 'react-native-fs';

  const fs = fetch_blob.fs
  const dirs = fetch_blob.fs.dirs      
  const file_path = dirs.DCIMDir + "/bigjpg.png"

  // json.qr is base64 string "data:image/png;base64,..."

  var image_data = json.qr.split('data:image/png;base64,');
  image_data = image_data[1];

  RNFS.writeFile(file_path, image_data, 'base64')
  .catch((error) => {
    alert(JSON.stringify(error));
  });

我写了一篇关于此事的博客

http://1c7.me/react-native-save-base64-image-to-album/

此文介绍如何将Base64格式的图片保存到相册,详细步骤请参考上述链接。

4
您现在可以使用react native fetch blob来实现此功能。
只需将RNFS.writeFile替换为:
RNFetchBlob.fs.writeFile(file_path, image_data, 'base64')

如果您希望在本地操作系统查看文件,只需输入以下命令:
                if (isAndroid) {
                  RNFetchBlob.android.actionViewIntent(file_path, 'application/pdf');
                } else {
                  RNFetchBlob.ios.previewDocument(file_path);
                }

RNFetchBlob.fs.writeFile(file_path, image_data, 'base64') 返回一个四位数字作为响应。 - sznrbrt
目前 rn-fetch-blob 已被放弃。请参见 github.com/joltup/rn-fetch-blob。我甚至无法使用 haul 构建它。也许在 metro 上运行效果更好。 - Dave Welling

1
我在以下示例中得到了这个工作。
import RNFetchBlob from 'rn-fetch-blob';
import Permissions from 'react-native-permissions';

 takeSnapshot = async () => {
    const currentStatus = await Permissions.check('storage');

    if (currentStatus !== 'authorized') {
      const status = await Permissions.request('storage');

      if (status !== 'authorized') {
        return false;
      }
    }

    // put here your base64
    const base64 = '';

    const path = `${RNFetchBlob.fs.dirs.DCIMDir}/test11.png`;

    try {
      const data = await RNFetchBlob.fs.writeFile(path, base64, 'base64');
      console.log(data, 'data');
    } catch (error) {
      console.log(error.message);
    }
  };

请帮我,我想在React Native中的相册文件夹中显示我的图片。 - Samira Gheibipour
目前 rn-fetch-blob 已被弃用。请参见 https://github.com/joltup/rn-fetch-blob。我甚至无法在使用 haul 构建它。也许它与 metro 更兼容。 - Dave Welling

1

const path = `${RNFS.PicturesDirectoryPath}/My Album`;
await RNFS.mkdir(path);
return await fetch(uri)
   .then(res => res.blob())
   .then(image => {
      RNFetchBlob.fs.readFile(uri, "base64").then(data => {
         RNFS.appendFile(`${path}/${image.data.name}`, data, "base64").catch(
            err => {
               console.log("error writing to android storage :", err);
            }
         );
      });
   });


0

这对我很有效。

我想在React Native中将base64下载为图像

this.state.base64img是我的base64,不包括'data:image/png;base64,'

checkPermision = async () => {
    if (Platform.OS === 'ios') {
      this.downloadImage();
    } else {
      try {
        const granted = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
          {
            title: 'Storage Permission Required',
            message: 'App needs access to your storage to download photos',
          },
        );
        if (granted === PermissionsAndroid.RESULTS.GRANTED) {
          console.log('Storage permission Granted');
          this.downloadImage();
        } else {
          console.log('Storage permission not Granted');
        }
      } catch (error) {
        console.log('errro', error);
      }
    }
  };

   downloadImage() {
    let date = new Date();
    const { fs} = RNFetchBlob;
    const dirs = RNFetchBlob.fs.dirs;
    let PictureDir = fs.dirs.PictureDir;

    var path =  PictureDir + '/image_' +
    Math.floor(date.getTime() + date.getSeconds() / 2) +
    '.png';
    console.log("path :-",path,"dirs :-",dirs)


    RNFetchBlob.fs.writeFile(path, this.state.base64img, 'base64').then(res => {
      console.log('File : ', res);
      alert('Image downloaded successfully.');
    }).catch((error) => {
         alert(JSON.stringify(error));
       });

  }

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