拍照并保存
本页介绍如何配置 @unif/react-native-camera 完成拍照任务——单张拍摄、连续抓拍、JPEG 质量控制,以及同时提供多种拍摄模式时的 tab 切换与照片保留策略。
基本用法:单拍
最简场景:单拍模式,用户拍一张、确认后返回。
import React from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import { useCamera } from '@unif/react-native-camera';
const PhotoScreen = () => {
const [api, holder] = useCamera();
const handleCapture = async () => {
const res = await api.open({
cameraMode: [{ mode: 'single' }],
dataRetainedMode: 'clear',
});
if (res.code === 200) {
// res.data: CustomPhotoFile[] — 处理拍摄结果
}
};
return (
<View>
<TouchableOpacity onPress={handleCapture}>
<Text>拍照</Text>
</TouchableOpacity>
{holder}
</View>
);
};
逐行讲解:
cameraMode: [{ mode: 'single' }]— 只含一个single模式,底部不出现 tab。在dataRetainedMode: 'clear'下,用户按快门拍一张后直接进入确认预览页,点「确认」后open()resolve。res.code === 200— 用户完成确认才是成功;0是取消,其余错误码见 类型 → CameraResult。{holder}— 相机模态的宿主节点,必须渲染(见下方易错点)。
连拍
将 mode 改为 'continuous',用户可连续按快门拍多张,相机持续显示缩略图条,最终一次性确认所有照片。
const res = await api.open({
cameraMode: [{ mode: 'continuous' }],
dataRetainedMode: 'clear',
});
if (res.code === 200) {
const photos = res.data; // 本次连拍的所有照片
}
连拍模式不会每拍一张就进预览;用户点击缩略图可进入相册式预览查看 / 删除,确认后整批返回。
JPEG 质量控制
quality 控制 JPEG 压缩率,范围 0~1,默认 0.9。值越低文件越小、画质越差。
await api.open({
cameraMode: [
{ mode: 'single', quality: 0.75 }, // 更小的文件体积
],
dataRetainedMode: 'clear',
});
何时调低 quality
上传接口有大小限制时,可将 quality 设为 0.6~0.8 降低体积。对画质要求高的场景(如证件留档),保持默认 0.9 或设为 1。
多模式 tab 与保留策略
cameraMode 传入多项时,相机底部自动出现模式 tab(按数组顺序),供用户在拍摄过程中切换。此时 dataRetainedMode 决定切换模式时已拍照片的去留:
await api.open({
cameraMode: [
{ mode: 'single', quality: 0.9 },
{ mode: 'continuous' },
],
dataRetainedMode: 'retain', // 切模式时保留已拍照片
});
dataRetainedMode | 切换模式时的行为 |
|---|---|
'clear' | 先弹二次确认,确认后清空已拍照片(推荐用于大多数场景) |
'retain' | 保留已拍照片,合并进最终 res.data |
注意:在单拍模式下
'clear'还有一层语义——每拍一张后直接进入确认预览(见 基本用法)。
易错点(Incorrect / Correct)
1. 不渲染 holder → 相机不弹
// ❌ Incorrect:拿了 holder 却没放进 React 树
const [api, holder] = useCamera();
return <Button title="拍照" onPress={() => api.open(cfg)} />; // api.open() 静默无效
// ✅ Correct:holder 必须在树里(位置不限)
const [api, holder] = useCamera();
return (
<View>
<Button title="拍照" onPress={() => api.open(cfg)} />
{holder}
</View>
);
2. 把 0 当成功(只有 200 才是成功)
// ❌ Incorrect:0 是取消,取消时 data 为空
const res = await api.open(cfg);
if (res.code === 0) use(res.data);
// ✅ Correct:200 才是成功
const res = await api.open(cfg);
if (res.code === 200) use(res.data);
else if (res.code === 0) { /* 用户取消,静默 */ }
else { /* 403 / 404 / 500 兜底处理 */ }
平台差异 / 注意事项
真机验证
相机功能依赖原生摄像头,无法在模拟器中预览实际效果,请在真机上完成最终验证。
权限配置
首次调用 api.open() 前,确认 Info.plist(iOS)与 AndroidManifest.xml(Android)已声明相机权限。详见 安装 → 配置权限。