Expo 相机与媒体库实战:扫码、拍照与本地保存
Created on
前言
相机和相册是最常见的原生能力之一,从扫码登录到拍照上传几乎每个 App 都会用到。Expo 提供了 expo-camera 与 expo-media-library,可以在不写原生代码的情况下完成大部分需求。
本文以“扫码 + 拍照 + 保存到相册”为例,演示完整接入流程。
安装依赖
expo install expo-camera expo-media-library
权限申请
相机和媒体库都需要权限,建议在页面初始化时统一处理:
import { useEffect, useState } from "react";
import { Camera } from "expo-camera";
import * as MediaLibrary from "expo-media-library";
export function useCameraPermissions() {
const [cameraGranted, setCameraGranted] = useState(false);
const [mediaGranted, setMediaGranted] = useState(false);
useEffect(() => {
(async () => {
const camera = await Camera.requestCameraPermissionsAsync();
const media = await MediaLibrary.requestPermissionsAsync();
setCameraGranted(camera.status === "granted");
setMediaGranted(media.status === "granted");
})();
}, []);
return { cameraGranted, mediaGranted };
}
扫码功能(BARCODE)
Expo Camera 内置条码扫描能力,常用场景是二维码登录或支付确认:
import { useRef, useState } from "react";
import { CameraView } from "expo-camera";
export function QrScanner() {
const [scanned, setScanned] = useState(false);
const onBarcodeScanned = ({ data }: { data: string }) => {
if (scanned) return;
setScanned(true);
console.log("扫码结果:", data);
};
return (
<CameraView
style={{ flex: 1 }}
barcodeScannerSettings={{ barcodeTypes: ["qr"] }}
onBarcodeScanned={onBarcodeScanned}
/>
);
}
建议加入“重新扫描”的交互按钮,避免连续触发。
拍照与保存到相册
import { useRef } from "react";
import { CameraView } from "expo-camera";
import * as MediaLibrary from "expo-media-library";
export function CameraCapture() {
const cameraRef = useRef<CameraView | null>(null);
const takePhoto = async () => {
const photo = await cameraRef.current?.takePictureAsync({
quality: 0.8,
skipProcessing: true,
});
if (!photo?.uri) return;
const asset = await MediaLibrary.createAssetAsync(photo.uri);
await MediaLibrary.createAlbumAsync("MyApp", asset, false);
};
return <CameraView ref={cameraRef} style={{ flex: 1 }} />;
}
这里用 createAlbumAsync 统一管理相册,也可以只保存到系统默认相册。
常见问题与建议
- Android 需要在
app.json中配置权限描述,否则无法上架 - 扫码场景建议关闭后置闪光灯时增加补光按钮
- 上传前建议对图片做压缩或裁剪,减少网络成本
小结
Expo 已经覆盖了绝大多数相机与媒体库需求。对于常见扫码、拍照、保存的场景,无需写原生代码就能落地。若后续需要更深度的相机控制(如 RAW 或专业级参数),再考虑引入自定义 native module。