最简路径是直接调用uni.chooseimage({sourcetype:['camera']}),参数必须为数组且真机有效;ios需至少两项如['camera','album'],返回tempfilepaths[0]可直传预览或上传,保存相册须额外调用uni.saveimagetophotosalbum。

uni.chooseImage 调用相机拍照最简路径
直接用 uni.chooseImage 是最快、最稳的方式,90% 场景下不需要写 <camera></camera> 组件或手动处理权限状态。它内部已封装平台差异,真机上点开就是系统原生相机界面。
关键不是“能不能调”,而是参数写对没写对:
-
sourceType必须是数组,哪怕只想要拍照也要写成['camera'],不能是字符串'camera' - iOS 要求至少两个选项(比如
['camera', 'album']),否则弹窗直接失败,报错no suitable source -
sizeType建议同时传['original', 'compressed'],避免某些 Android 机型因只传['original']导致黑屏或无响应 - 返回的
res.tempFilePaths[0]就是可直接预览、上传、保存的临时路径,不用额外转 base64
拍照后保存到相册必须显式调用 uni.saveImageToPhotosAlbum
uni.chooseImage 本身不保存图片——它只返回临时文件路径。想存进相册,必须额外一步调用 uni.saveImageToPhotosAlbum,且这个 API 在 iOS 和 Android 行为一致,但有硬性前提:
- 路径必须是本地临时路径(即
res.tempFilePaths[0]这种file://或uni-file://开头的),网络地址或 base64 会静默失败 - Android 需要
WRITE_EXTERNAL_STORAGE权限(manifest.json中已声明);iOS 不需要额外权限,但首次调用会弹系统授权框 - 保存失败常见原因是:路径已过期(临时文件有效期短,尤其 H5 端仅几秒)、路径被误改(比如拼了
https://前缀)、或用户拒绝了相册授权
示例调用:
uni.saveImageToPhotosAlbum({
filePath: this.tempFilePath,
success: () => uni.showToast({ title: '已保存到相册' }),
fail: (err) => console.error('保存失败', err)
})
如何判断这张图是“刚拍的”而不是“从相册选的”
保存前常需区分来源:拍照图才存相册,相册图不重复保存。不能靠 sourceType 参数判断(因为用户可能先选 ['camera', 'album'] 再点相册),得看路径特征:
- 路径含
camera、DCIM、Pictures、tmp_、temp等关键词 → 大概率是拍照 - 路径含
compressed、wxfile://、album、gallery→ 基本是相册选图 - 更稳妥的做法是:在
uni.chooseImage成功回调里,记录当前sourceType选择项,比如用户点的是“拍照”按钮,就固定传['camera'],然后保存逻辑只走这一路
别依赖 res.tempFiles[0].size 或时间戳,不同设备、系统版本下特征不稳定。
权限和兼容性最容易被忽略的三个点
真机调试时出问题,80% 出在这三处:
-
manifest.json里 Android 缺少WRITE_EXTERNAL_STORAGE,iOS 缺少相册权限描述文案 → 打包后保存直接失败,且无明确报错 - H5 端根本无法调起摄像头,
uni.chooseImage会降级为文件选择框,别在 H5 上测试“拍照”逻辑 - 微信小程序开发版(
envVersion: develop)默认禁用相机,必须切到trial或release才能触发,否则静默无反应
复杂点在于:iOS 相册授权和相机授权是两个独立开关,用户可能开了相机但关了相册,保存时才会暴露问题——所以保存前最好用 uni.getSetting 检查 scope.writePhotosAlbum 状态,引导用户去设置页开启。











