react-native-fs:如何读取本地图片(获取本地文件的base64)

react-native-fs: How to read local images (Get base64 of local file)

我的应用程序中有本地文件,我是这样读的:

<Image source={require("../../img/pic1.jpg") />

如何使用 RNFS.readFile(filepath, "base64"); 读取此文件 使用 RNFS.readFile("../../img/pic1.jpg", "base64"); 给我错误 "no such file"

react-native-fs 将仅访问设备存储中的文件。所以这个问题让人进退两难。这些文件在构建时捆绑在一起,那么我们如何在开发和生产中访问它们?

我的项目结构

├── android
├── app
│   └── assets
│       └── images
└── ios

我将图像存储在 ./app/assets/images/

发展

开发调试时,文件通过地铁捆绑器提供给设备,因此它们实际上并未存储在设备上.因此无法从设备存储访问它们。您必须在开发时提供某种 mocked 功能。可以使用 __DEV__ 允许不同的功能 运行 取决于环境 https://facebook.github.io/react-native/docs/javascript-environment

if (__DEV__) {
  // do something in development
} else {
  // do something in production
}

生产

根据一些研究,似乎可以在生产环境中访问这些文件。

iOS

我发现这些文件位于 MainBundlePath 中名为 assets 的文件夹中。

因此,如果您想在我的本地目录 ./app/assets/images/image.png 中访问以下文件,您需要以下文件路径:RNFS.MainBundlePath + /assets/app/assets/images/image.png 才能在设备上访问它。

您可以通过查看 ipa 生成的 Packaging.log 来查看文件路径。

Android

Android 没有仅在 iOS 上的名为 MainBundlePath 的文件夹。我花了一些时间研究和查看设备上的不同文件夹,但我无法访问捆绑的图像。似乎无法以我们希望使用 react-native-fs.

的方式访问它们

可能的解决方案

rn-fetch-blob

rn-fetch-blob 具有 iosAndroid 从资产目录中读取的功能

要访问 iOS 的文件,您可以这样做:

RNFetchBlob.fs.stat(fs.dirs.MainBundleDir + '/whatever/files/you/added.mp3').then( stats => {...});

对于 Android 你会做这样的事情:

RNFetchBlob.fs.stat(fs.asset('/whatever/files/you/added.mp3').then( stats => {...});

它确实给出了有关资产被 Gradle 压缩的警告。

Gradle will compress bundled assets by default. In order to interact with asset files with this module, compression must be disabled. Please see How to access files from assets for more detail.

这可以解释为什么我在使用 react-native-fs

查找时无法在 Android 中找到任何资产

您可以在此处阅读有关使用 rn-fetch-blob 及其文件系统的更多信息 https://github.com/joltup/rn-fetch-blob#user-content-file-system

将文件存储在本机项目中

而不是依赖捆绑器为您打包图像并将它们放在设备上。您可以将它们的副本存储在 iOSAndroid 项目中。这样做的好处是图像可以在开发中使用,但是您会多次存储图像,这可能会导致应用程序变大。

将图像存储为 base64

您可以将图像作为 base64 字符串存储在 json 文件中,然后您的应用程序需要这些。这将意味着您已经在 base64 中拥有它们(因此应用程序不必进行任何转换)但是您将再次增加应用程序的大小。如果只有少量图像,这可能是最简单的选择。

只需使用文件名 = response.uri.replace('file:', '')

最终代码:

if (Platform.OS === 'ios') {
      filename = response.uri.replace('file:', '')
} else {
      filename = response.uri
}

现在正在工作...

2021 年使用 RNFS 的更新

iOS

Andrew 关于使用 RNFS.MainBundlePath 的建议仍然有效。

Android

RNFS 可以读取应用资产目录中的文件:

RNFS.readFileAssets(filepath:string, encoding?: string)

编码可以是 utf8(默认)、ascii 或 base64 之一。使用 base64 读取二进制文件。 filepath 是从资产文件夹根目录到文件的相对路径。

例如,如果您的文件直接位于资产目录中:

RNFS.readFileAssets('coolimage.png', 'base64');

https://github.com/itinance/react-native-fs#readfileassetsfilepathstring-encoding-string-promisestring