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
具有 ios
和 Android
从资产目录中读取的功能
要访问 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
将文件存储在本机项目中
而不是依赖捆绑器为您打包图像并将它们放在设备上。您可以将它们的副本存储在 iOS
和 Android
项目中。这样做的好处是图像可以在开发中使用,但是您会多次存储图像,这可能会导致应用程序变大。
将图像存储为 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');
我的应用程序中有本地文件,我是这样读的:
<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
具有 ios
和 Android
从资产目录中读取的功能
要访问 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
您可以在此处阅读有关使用 rn-fetch-blob
及其文件系统的更多信息 https://github.com/joltup/rn-fetch-blob#user-content-file-system
将文件存储在本机项目中
而不是依赖捆绑器为您打包图像并将它们放在设备上。您可以将它们的副本存储在 iOS
和 Android
项目中。这样做的好处是图像可以在开发中使用,但是您会多次存储图像,这可能会导致应用程序变大。
将图像存储为 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');