Expo项目中如何读取相册图片的字节数据?
解决方案
ph:// 是iOS照片库的专属URI格式,Expo FileSystem无法直接读取这类URI——它指向的是系统照片库的抽象资源,而非应用沙盒内可直接访问的文件。你可以通过以下两种方式获取图片字节数据:
方法一:复制资产到应用沙盒后读取
使用MediaLibrary.copyAssetToAsync将照片库资源复制到Expo应用可访问的目录(如文档目录或缓存目录),得到file://格式的URI后,再用FileSystem读取:
import * as MediaLibrary from 'expo-media-library'; import * as FileSystem from 'expo-file-system'; // 获取相册资产列表 const { assets } = await MediaLibrary.getAssetsAsync({ first: 100, sortBy: "creationTime", }); // 遍历处理每个资产 for (const asset of assets) { // 定义本地存储路径(用asset.id做文件名避免重复) const localFilePath = `${FileSystem.documentDirectory}${asset.id}.${asset.filename.split('.').pop()}`; // 复制资产到本地目录,返回file:// URI const localUri = await MediaLibrary.copyAssetToAsync(asset.uri, localFilePath); // 读取base64格式的字节数据 const base64Data = await FileSystem.readAsStringAsync(localUri, { encoding: FileSystem.EncodingType.Base64, }); // 这里可将base64Data用于备份逻辑 // 可选:处理完成后删除本地副本,释放空间 await FileSystem.deleteAsync(localUri); }
方法二:通过ImageManipulator直接获取Base64
如果只需要Base64格式的字节数据,也可以用expo-image-manipulator的manipulateAsync方法直接转换,无需复制文件:
import * as MediaLibrary from 'expo-media-library'; import * as ImageManipulator from 'expo-image-manipulator'; const { assets } = await MediaLibrary.getAssetsAsync({ first: 100, sortBy: "creationTime", }); for (const asset of assets) { // 直接将ph:// URI的图片转换为Base64 const { base64 } = await ImageManipulator.manipulateAsync( asset.uri, [], // 不做任何图片编辑操作 { base64: true } ); // base64即为图片的字节数据(Base64编码) }
注意事项
- 确保已申请并获取了
MEDIA_LIBRARY权限(iOS需额外配置PHOTO_LIBRARY或PHOTO_LIBRARY_ADD_ONLY权限,根据Expo版本和需求调整); - 方法一中的本地文件需按需清理,避免占用过多设备存储空间;
- 方法二适合仅需Base64数据的场景,无需额外存储文件,效率更高。
内容的提问来源于stack exchange,提问作者Adnesh Dhamangaonkar
相关产品推荐
相关产品推荐

