将带构造函数的React Native模糊检测类组件转为函数组件
React Native 类组件转函数组件:图像模糊检测实现
以下是将原类组件迁移为函数组件的完整实现,保留了拍照、模糊检测核心功能,适配React Hooks语法:
import React, { useState, useEffect, useRef } from 'react'; import { View, Button, Text, StyleSheet } from 'react-native'; import { Camera } from 'react-native-camera'; import OpenCV from 'react-native-opencv'; const CameraScreen = ({ navigation }) => { // 替换类组件state为useState钩子 const [isCameraReady, setIsCameraReady] = useState(false); const [hasPermission, setHasPermission] = useState(null); const [isTakingPhoto, setIsTakingPhoto] = useState(false); const [blurLevel, setBlurLevel] = useState(null); const camera = useRef(null); // 替换componentDidMount的权限请求逻辑 useEffect(() => { const requestCameraPermission = async () => { const { status } = await Camera.requestCameraPermissionsAsync(); setHasPermission(status === 'granted'); }; requestCameraPermission(); }, []); // 拍照逻辑 const takePicture = async () => { if (!isCameraReady || isTakingPhoto) return; setIsTakingPhoto(true); try { const photo = await camera.current.takePictureAsync({ quality: 0.8 }); await detectBlur(photo.uri); } catch (error) { console.error('拍照失败:', error); } finally { setIsTakingPhoto(false); } }; // 模糊检测核心逻辑(基于OpenCV) const detectBlur = async (imageUri) => { try { // 加载图像并转灰度图 const mat = await OpenCV.imreadAsync(imageUri); const grayMat = await OpenCV.cvtColorAsync(mat, OpenCV.COLOR_RGBA2GRAY); // 用Laplacian算子计算边缘方差,方差越小图像越模糊 const laplacian = await OpenCV.LaplacianAsync(grayMat, OpenCV.CV_64F); const { stdDev } = await OpenCV.meanStdDevAsync(laplacian); const blurValue = stdDev[0] ** 2; // 根据阈值划分模糊等级 if (blurValue < 10) { setBlurLevel('图像模糊'); } else if (blurValue < 50) { setBlurLevel('图像轻度模糊'); } else { setBlurLevel('图像清晰'); } // 释放OpenCV Mat资源,避免内存泄漏 await OpenCV.releaseAsync(mat); await OpenCV.releaseAsync(grayMat); await OpenCV.releaseAsync(laplacian); } catch (error) { console.error('模糊检测失败:', error); setBlurLevel('检测失败'); } }; if (hasPermission === null) { return <View />; } if (hasPermission === false) { return <Text>没有相机权限</Text>; } return ( <View style={styles.container}> <Camera ref={camera} style={styles.camera} onCameraReady={() => setIsCameraReady(true)} type={Camera.Constants.Type.back} /> <View style={styles.buttonContainer}> <Button title={isTakingPhoto ? '拍照中...' : '拍照'} onPress={takePicture} disabled={isTakingPhoto || !isCameraReady} /> </View> {blurLevel && <Text style={styles.blurText}>检测结果: {blurLevel}</Text>} </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, camera: { flex: 1, width: '100%', }, buttonContainer: { position: 'absolute', bottom: 50, width: '100%', alignItems: 'center', }, blurText: { position: 'absolute', top: 20, fontSize: 18, color: 'white', backgroundColor: 'rgba(0,0,0,0.7)', padding: 8, borderRadius: 4, }, }); export default CameraScreen;
核心迁移点说明
- 状态管理:将类组件的
this.state拆分为多个useState钩子,实现更细粒度的状态控制,避免this绑定问题。 - 生命周期适配:原
componentDidMount中的权限请求逻辑,迁移到useEffect钩子(空依赖数组确保仅初始化执行一次)。 - 实例引用:用
useRef获取相机组件实例,替代类组件的this.camera。 - 方法重构:原类组件的类方法全部改为函数组件内部的异步函数,逻辑完全保留,写法更简洁。
- OpenCV逻辑复用:完整保留了基于Laplacian算子的模糊检测核心逻辑,同时添加了Mat资源释放步骤,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Ronuel Banderada Moralita
相关产品推荐
相关产品推荐

