Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/470.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应本机Android全屏摄像头,同时保持正确的比例_Javascript_Android_Reactjs_React Native_Android Camera - Fatal编程技术网

Javascript 反应本机Android全屏摄像头,同时保持正确的比例

Javascript 反应本机Android全屏摄像头,同时保持正确的比例,javascript,android,reactjs,react-native,android-camera,Javascript,Android,Reactjs,React Native,Android Camera,我想让摄像头预览占据整个屏幕,就像snapchat在应用程序中所做的那样,让摄像头预览占据整个屏幕。问题是在预览占据屏幕的同时保持屏幕的比例不变。有没有办法在react native中实现这一点?下面的代码生成了一个预览,底部有一个黑色条,我必须保留该条,以便为相机预览提供正确的纵横比。 我假设我必须将预览的宽度负移到帧外才能实现这一点,但我没有尝试,我不确定这是否是正确的方法 const { height, width } = Dimensions.get('window') const

我想让摄像头预览占据整个屏幕,就像snapchat在应用程序中所做的那样,让摄像头预览占据整个屏幕。问题是在预览占据屏幕的同时保持屏幕的比例不变。有没有办法在react native中实现这一点?下面的代码生成了一个预览,底部有一个黑色条,我必须保留该条,以便为相机预览提供正确的纵横比。 我假设我必须将预览的宽度负移到帧外才能实现这一点,但我没有尝试,我不确定这是否是正确的方法


const { height, width } = Dimensions.get('window')

const CameraScreen = ({ navigation, route }) => {
    let checkMarkSet = null
    if (route.params) {
        checkMarkSet = true
    }

    // RATIO SETTER
    const [imagePadding, setImagePadding] = useState(0)
    const [ratio, setRatio] = useState('4:3') // default is 4:3
    const screenRatio = height / width
    const [isRatioSet, setIsRatioSet] = useState(false)
    async function prepareRatio() {
        let desiredRatio = '4:3' // Start with the system default
        // This issue only affects Android
        if (Platform.OS === 'android') {
            const ratios = await cameraRef.current.getSupportedRatiosAsync()
            let distances = {}
            let realRatios = {}
            let minDistance = null
            for (const ratio of ratios) {
                const parts = ratio.split(':')
                const ratioHeight = parseInt(parts[0])
                const ratioWidth = parseInt(parts[1])
                const realRatio = ratioHeight / ratioWidth
                realRatios[ratio] = realRatio
                // ratio can't be taller than screen, so we don't want an abs()
                const distance = screenRatio - realRatio
                distances[ratio] = realRatio
                if (minDistance == null) {
                    minDistance = ratio
                } else {
                    if (distance >= 0 && distance < distances[minDistance]) {
                        minDistance = ratio
                    }
                }
            }
            // set the best match
            desiredRatio = minDistance

            //  calculate the difference between the camera width and the screen height
            const remainder = Math.floor(
                (height - realRatios[desiredRatio] * width) / 2
            )

            // set the preview padding and preview ratio
            setImagePadding(remainder / 2)
            console.log(`okay look ${remainder / 2}`)
            setRatio(desiredRatio)
            // Set a flag so we don't do this
            // calculation each time the screen refreshes
            setIsRatioSet(true)
        }
    }

    const setCameraReady = async () => {
        if (!isRatioSet) {
            await prepareRatio()
        }
    }
    // RATIO SETTER

    const [type, setType] = useState(Camera.Constants.Type.back)
    const [activateCamera, setActivateCamera] = useState(false)
    const [video, setVideo] = useState('')
    const [showVideoModal, setShowVideoModal] = useState(false)
    const insets = useSafeAreaInsets()

    useFocusEffect(() => {
        if (navigation.isFocused()) {
            setActivateCamera(true)
        }
    })

    const [pic, setPic] = useState(null)

    const [showModal, setShowModal] = useState(false)

    const cameraRef = useRef()



    return (
        <View
            style={{
                ...styles.container,
                // paddingTop: Platform.OS === 'android' ? insets.top : null,
            }}
        >
            <StatusBar
                style=""
                translucent
                backgroundColor="rgba(255,255,255,0)"
            />
            <PinchGestureHandler onGestureEvent={onPinchGesture}>
                <Reanimated.View
                    style={{
                        flex: 1,
                        backgroundColor: 'black',
                        justifyContent: 'flex-start',
                        paddingBottom: imagePadding * 4,
                    }}
                >
                    {activateCamera && (
                        <Camera
                            style={{
                                // marginTop: imagePadding,
                                // marginBottom: imagePadding,
                                flex: 1,
                                // height: 733,
                            }}
                            ref={cameraRef}
                            type={type}
                            flashMode={flashMode}
                            zoom={zooming}
                            onCameraReady={setCameraReady}
                            ratio={ratio}
                            maxDuration={10000}
                            autoFocus="on"
                        >
                            <View
                                style={[
                                    styles.contentContainer,
                                    {
                                        paddingTop: insets.top,
                                        paddingBottom: insets.bottom,
                                        top: insets.top,
                                        bottom: insets.bottom,
                                    },
                                ]}
                            >
                                <View style={styles.topLeftCont}>
                                    <TouchableOpacity
                                        onPress={flipCameraHandler}
                                    >
                                        <Entypo
                                            name="loop"
                                            size={27}
                                            color="white"
                                            style={styles.flipIcon}
                                        />
                                    </TouchableOpacity>

                                    <TouchableOpacity
                                        onPress={flashSwitchHandler}
                                    >
                                        <Ionicons
                                            name={
                                                flashMode !== 'off'
                                                    ? 'flash'
                                                    : 'flash-off'
                                            }
                                            size={27}
                                            color="white"
                                            style={styles.cameraSettingsButton}
                                        />
                                    </TouchableOpacity>
                                </View>

                                <CameraButton
                                    style={{
                                        ...styles.floatingPlusCont,
                                        left: width / 2 - 45,
                                    }}
                                    onLongPress={beginRecording}
                                    onEndPress={endRecording}
                                    onTap={takePictureHandler}
                                />
                            </View>
                        </Camera>
                    )}
                </Reanimated.View>
            </PinchGestureHandler>
    )
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'flex-start',
    },
    contentContainer: {
        flex: 1,
        position: 'absolute',
        right: 0,
        left: 0,
    },
    camera: {
        flex: 1,
        flexDirection: 'row',
    },

    topLeftCont: {
        position: 'absolute',
        width: 45,
        top: 0,
        right: 10,
        borderRadius: 20,
        backgroundColor: 'rgba(184,184,184,0.42)',
        alignItems: 'center',
        justifyContent: 'space-between',
        // flexDirection: 'row',
        padding: 5,
    },
    flipIcon: {
        marginVertical: 7,
        transform: [
            {
                rotate: '90deg',
            },
        ],
    },
    cameraSettingsButton: { marginVertical: 7 },
    modal: {
        flex: 1,
        position: 'absolute',
        top: 0,
        right: 0,
        left: 0,
        bottom: 0,
    },
    takenImage: { flex: 1 },
    bottomCont: {
        flex: 1,
        justifyContent: 'flex-end',
        padding: 10,
    },
    bottomButtonsCont: {
        width: '100%',
        justifyContent: 'space-between',
        flexDirection: 'row',
        paddingHorizontal: 5,
    },
    floatingPlusCont: {
        bottom: 25,
        position: 'absolute',
        width: 90,
        height: 90,
        borderRadius: 45,
    },
    loadingView: {
        backgroundColor: 'rgba(0,0,0,0.4)',
        justifyContent: 'center',
        alignItems: 'center',
    },
})

export default CameraScreen

const{height,width}=Dimensions.get('window')
常量摄影机屏幕=({导航,路线})=>{
设checkMarkSet=null
if(路由参数){
checkMarkSet=true
}
//比率设定器
常量[imagePadding,setImagePadding]=useState(0)
const[ratio,setRatio]=useState('4:3')//默认值为4:3
常数屏幕比率=高度/宽度
const[isRatioSet,setIsRatioSet]=useState(false)
异步函数prepareRatio(){
让desiredRatio='4:3'//从系统默认值开始
//这个问题只影响Android
如果(Platform.OS==='android'){
const ratio=wait cameraRef.current.getSupportedRatiosAsync()
设距离={}
设realtratio={}
让minDistance=null
for(比率的常数比){
常量部分=比率。拆分(“:”)
const ratioHeight=parseInt(部分[0])
const ratioWidth=parseInt(部分[1])
const realRatio=比率高度/比率宽度
真实比率[比率]=真实比率
//比率不能高于屏幕,所以我们不想要abs()
常数距离=屏幕比率-真实比率
距离[比率]=实际比率
如果(minDistance==null){
距离=比率
}否则{
如果(距离>=0&&distance{
如果(!isRatioSet){
等待准备
}
}
//比率设定器
const[type,setType]=useState(Camera.Constants.type.back)
常数[activateCamera,setActivateCamera]=useState(false)
const[video,setVideo]=useState(“”)
const[showVideoModal,setShowVideoModal]=useState(false)
常量插入=使用安全区域插入()
UseFocuseEffect(()=>{
if(navigation.isFocused()){
setActivateCamera(真)
}
})
const[pic,setPic]=useState(null)
const[showmodel,setshowmodel]=useState(false)
const cameraRef=useRef()
返回(
{activateCamera&&(
)}
)
}
const styles=StyleSheet.create({
容器:{
弹性:1,
justifyContent:“flex start”,
},
内容容器:{
弹性:1,
位置:'绝对',
右:0,,
左:0,,
},
摄像机:{
弹性:1,
flexDirection:'行',
},
topLeftCont:{
位置:'绝对',
宽度:45,
排名:0,
右:10,,
边界半径:20,
背景颜色:“rgba(184,0.42)”,
对齐项目:“居中”,
justifyContent:'之间的空间',
//flexDirection:'行',
填充:5,
},
翻转图标:{
Margin:7,
转换:[
{
旋转:“90度”,
},
],
},
cameraSettingsButton:{MargInvertial:7},
模态:{
弹性:1,
位置:'绝对',
排名:0,
右:0,,
左:0,,
底部:0,
},
takenImage:{flex:1},
底部续:{
弹性:1,
justifyContent:“柔性端”,
填充:10,
},
底部按钮图标:{
宽度:“100%”,
justifyContent:'之间的空间',
flexDirection:'行',
填充水平面:5,
},
浮点数:{
底数:25,
位置:'绝对',
宽度:90,
身高:90,
边界半径:45,
},
加载视图:{
背景颜色:“rgba(0,0,0,0.4)”,
为内容辩护:“中心”,
对齐项目:“居中”,
},
})
导出默认摄像机屏幕