0Pricing
React Native Academy · 课时

使用 expo-camera 访问相机

请求相机权限,渲染带快门按钮的 Camera 组件,拍摄照片,并在 Image 组件中显示拍摄照片的 URI。

使用 expo-camera 访问相机 是 CoddyKit 上的免费 React Native Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Native Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Native Academy 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

Why Use expo-camera?

expo-camera provides a React Native component that renders a live camera preview and lets users capture photos and videos. It works in both iOS and Android and integrates cleanly with Expo's managed workflow. Using expo-camera you can build features like profile photo capture, document scanning, QR code reading, and real-time image capture without writing any native code.

Installing expo-camera

Install expo-camera with the Expo install command so Expo picks the SDK-compatible version. After installation, expo-camera's native modules are linked automatically in an Expo managed project. In a bare workflow project you must also run pod install for iOS after installing.

npx expo install expo-camera

Requesting Camera Permission

Before showing the camera, you must request the user's permission. Use Camera.requestCameraPermissionsAsync() and check the returned status field. If the status is not 'granted', the camera cannot be shown. Always request permission in response to a user action (like tapping a button) so the OS permission dialog appears at a natural moment.

import { Camera } from 'expo-camera';

const [permission, requestPermission] = Camera.useCameraPermissions();

if (!permission) {
  return <ActivityIndicator />;
}

if (!permission.granted) {
  return (
    <View>
      <Text>Camera access is required to take photos.</Text>
      <Button title='Grant Permission' onPress={requestPermission} />
    </View>
  );
}

Rendering the Camera Component

Once permission is granted, render the CameraView component from expo-camera. Give it a style with defined dimensions — it will not render if it has no size. The camera preview fills the allocated space. Use facing to set the initial lens: 'back' for the rear camera or 'front' for the selfie camera.

import { CameraView } from 'expo-camera';
import { StyleSheet } from 'react-native';

export default function CameraScreen() {
  const [permission, requestPermission] = Camera.useCameraPermissions();
  const cameraRef = React.useRef(null);

  if (!permission?.granted) return <PermissionPrompt onPress={requestPermission} />;

  return (
    <View style={styles.container}>
      <CameraView style={styles.camera} facing='back' ref={cameraRef} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  camera: { flex: 1 },
});

Capturing a Photo

Attach a ref to the CameraView component and call ref.current.takePictureAsync() to capture a photo. This returns a CameraCapturedPicture object with a uri property pointing to the captured image on the device's temporary file system. Display the captured image using React Native's Image component.

const [photo, setPhoto] = React.useState(null);

async function takePicture() {
  if (cameraRef.current) {
    const captured = await cameraRef.current.takePictureAsync({
      quality: 0.8,     // 0 to 1, lower = smaller file
      base64: false,    // true to include base64 string in result
    });
    setPhoto(captured.uri);
  }
}

Displaying the Captured Image

Once a photo URI is captured, switch the view from the camera preview to an Image component showing the captured photo. Provide 'Retake' and 'Use Photo' buttons so the user can confirm or discard the capture. This preview-before-confirm pattern is standard in camera apps and prevents accidental bad photos.

if (photo) {
  return (
    <View style={styles.container}>
      <Image source={{ uri: photo }} style={styles.camera} />
      <View style={styles.buttonRow}>
        <Button title='Retake' onPress={() => setPhoto(null)} />
        <Button title='Use Photo' onPress={() => onPhotoSelected(photo)} />
      </View>
    </View>
  );
}

Toggling Between Front and Back Camera

Allow users to switch between the front and back camera by toggling a state variable. Pass the state to the facing prop of CameraView. React Native handles the camera switch automatically when the prop changes. Add a flip button in the UI overlay for intuitive UX.

const [facing, setFacing] = React.useState<'back' | 'front'>('back');

function toggleCamera() {
  setFacing((current) => (current === 'back' ? 'front' : 'back'));
}

<CameraView style={styles.camera} facing={facing} ref={cameraRef}>
  <TouchableOpacity onPress={toggleCamera} style={styles.flipButton}>
    <Ionicons name='camera-reverse' size={32} color='white' />
  </TouchableOpacity>
  <TouchableOpacity onPress={takePicture} style={styles.shutterButton} />
</CameraView>

Scanning QR Codes

CameraView also supports barcode scanning, including QR codes. Set the onBarcodeScanned prop to a callback function. The callback fires with a result object containing the barcode type and data (the decoded string). Pause scanning after the first result to avoid handling the same code multiple times.

const [scanned, setScanned] = React.useState(false);

function handleBarcodeScan({ type, data }) {
  if (!scanned) {
    setScanned(true);
    Alert.alert('Scanned!', 'Type: ' + type + '\nData: ' + data, [
      { text: 'Scan Again', onPress: () => setScanned(false) },
    ]);
  }
}

<CameraView
  style={styles.camera}
  onBarcodeScanned={scanned ? undefined : handleBarcodeScan}
  barcodeScannerSettings={{ barcodeTypes: ['qr', 'ean13'] }}
/>

Adjusting Camera Quality

The pictureSize prop lets you control the resolution of captured images. Use Camera.getAvailablePictureSizesAsync to query the device's supported sizes and let users choose. Higher resolution photos are better quality but produce larger files. For user-facing profile photos, a medium resolution (around 1080p) is usually the right balance.

const photo = await cameraRef.current.takePictureAsync({
  quality: 0.7,
  exif: false,      // skip EXIF metadata to reduce file size
  skipProcessing: true, // faster capture on Android
});
console.log('Photo size:', photo.width, 'x', photo.height);

Saving to the Media Library

A captured photo's uri points to a temporary location. To save it permanently to the device's photo gallery, use expo-media-library. Call MediaLibrary.saveToLibraryAsync(photo.uri) after capture. Remember to request MediaLibrary permission separately in addition to the camera permission.

import * as MediaLibrary from 'expo-media-library';

async function savePhoto(uri: string) {
  const { status } = await MediaLibrary.requestPermissionsAsync();
  if (status === 'granted') {
    await MediaLibrary.saveToLibraryAsync(uri);
    Alert.alert('Saved!', 'Photo saved to your gallery.');
  }
}

Camera Overlay UI Tips

The CameraView component can render child components on top of the camera preview, acting as a UI overlay. Place shutter buttons, flash toggles, and crop guides as absolute-positioned children inside CameraView. Use a StyleSheet with position: 'absolute' and bottom / top coordinates to position overlay controls intuitively over the live preview.

Quick Check

Test your understanding of React Native Mobile Development concepts from this lesson.

Lesson Recap

In this lesson you learned: Camera.useCameraPermissions handles requesting and checking camera permission before rendering the viewfinder, CameraView with a ref lets you call takePictureAsync to capture a photo and get its URI, and onBarcodeScanned enables QR code reading with the same camera component. Next up we explore reading GPS location with expo-location.

常见问题解答

「使用 expo-camera 访问相机」课时是免费的吗?

是的 — 「使用 expo-camera 访问相机」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Native Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Native Academy 课程共包含 4 节课。

「使用 expo-camera 访问相机」这节课中我会学到什么?

请求相机权限,渲染带快门按钮的 Camera 组件,拍摄照片,并在 Image 组件中显示拍摄照片的 URI。 你通过在浏览器中直接运行的动手代码来练习 React Native Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 React Native Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 React Native Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「使用 expo-camera 访问相机」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 React Native Academy 课中编写并运行代码吗?

能。每节 React Native Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 expo-camera 访问相机
  2. 使用 expo-location 读取 GPS 位置
  3. 安排本地通知
  4. 妥善处理权限
← 返回 React Native Academy