You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Native中实现拍摄图片的手绘标注功能?

针对 Expo Camera 拍照后添加手绘功能的最优方案

优先选 Expo 官方维护的 expo-sketch

作为 Expo 生态内的官方组件,完美适配你的 Expo 项目,和 expo-camera 兼容性拉满,无需额外配置原生代码。

  • 核心能力:支持在图片上绘制线条、调整笔触颜色/粗细,自带撤销、清空操作
  • 实现步骤:
    1. 拍照完成后拿到图片 URI
    2. 将图片作为 expo-sketch 的背景图传入
    3. 用户手绘结束后,调用 saveAsync() 方法导出带手绘层的图片
  • 代码示例:
import { Sketch } from 'expo-sketch';
import { Button, View } from 'react-native';
import { useState, useRef } from 'react';

export default function SketchScreen({ route }) {
  const capturedImageUri = route.params?.imageUri;
  const [savedUri, setSavedUri] = useState(null);
  const sketchRef = useRef(null);

  const saveSketch = async () => {
    if (sketchRef.current) {
      const uri = await sketchRef.current.saveAsync();
      setSavedUri(uri);
    }
  };

  return (
    <View style={{ flex: 1 }}>
      {capturedImageUri && (
        <Sketch
          ref={sketchRef}
          style={{ flex: 1 }}
          imageUri={capturedImageUri}
          strokeColor="#ff0000"
          strokeWidth={3}
        />
      )}
      <Button title="保存手绘图片" onPress={saveSketch} />
    </View>
  );
}

自定义手绘组件(适合高度定制需求)

如果需要特殊笔触效果或完全可控的逻辑,可以基于 react-native-gesture-handler 和 react-native-reanimated 结合 RN 内置的 Canvas 实现:

  • 核心逻辑:用手势库监听触摸事件,动画库处理实时绘制,Canvas 渲染线条和背景图
  • 优势:无第三方库依赖,完全自主可控,维护性强
  • 代码片段:
import { Canvas, Path, Image as CanvasImage } from 'react-native-canvas';
import { GestureHandlerRootView, PanGestureHandler } from 'react-native-gesture-handler';
import Animated, { useAnimatedGestureHandler, useSharedValue } from 'react-native-reanimated';

const CustomSketch = ({ imageUri }) => {
  const pathPoints = useSharedValue([]);

  const panHandler = useAnimatedGestureHandler({
    onStart: (e) => {
      pathPoints.value = [{ x: e.x, y: e.y }];
    },
    onActive: (e) => {
      pathPoints.value = [...pathPoints.value, { x: e.x, y: e.y }];
    },
  });

  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <PanGestureHandler onGestureEvent={panHandler}>
        <Canvas style={{ flex: 1 }}>
          <CanvasImage href={imageUri} style={{ width: '100%', height: '100%' }} />
          <Path
            d={pathPoints.value.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`).join(' ')}
            stroke="#000"
            strokeWidth={3}
            fill="transparent"
          />
        </Canvas>
      </PanGestureHandler>
    </GestureHandlerRootView>
  );
};

替代已停止维护的 react-native-sketch-canvas:用 react-native-sketch-view

这个库是活跃维护的替代方案,API 和旧库接近,迁移成本低,支持 Expo 项目(需配合 expo-dev-client 使用):

  • 支持背景图导入、笔触调整、撤销/重做、图片导出
  • 安装命令:npm install react-native-sketch-view

方案选择建议

  • 纯 Expo 项目直接选 expo-sketch,官方维护,集成成本最低
  • 需要定制手绘效果选自定义组件方案,完全可控
  • 想快速迁移旧代码选 react-native-sketch-view

内容的提问来源于stack exchange,提问作者fakermaker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 14:30:39