React | 在react中使用Video标签进行拍照生成Base64图片

功能

  1. 效果图
  2. 代码

点击一个按弹出一个框可以点击拍照生成Base64图片

效果图

在这里插入图片描述

上代码

import React, { PureComponent, Fragment } from 'react';
import { Button, Row, Col } from 'antd'

// import avatar from './avatar.png' // 背景图

//视频流
let trackStrem

/**
 * 参数
 * @param {getCameraRef} function 获取子类ref
 * @param {onChange} function 传递图片数据
 * @param {image} base64 图片数据
 */
export default class Camera extends PureComponent {

    state = {
        camState: 1
    }

    componentDidMount() {
    	// 如果没有对子类属性控制的需求可以直接注释这个回调函数 getCameraRef
        const { image, getCameraRef } = this.props;
        getCameraRef(this)
        if (image) {
            this.changeState(1)
        } else {
            this.changeState(2)
        }
    }

    componentWillUnmount() {
        this.closeCamera()
    }

    // 状态切换
    changeState = (state) => {
        switch (state) {
            case 1:
                this.setState({ camState: 1 })
                break;
            case 2:
                this.setState({ camState: 2 })
                this.openCamera()
                break;
            case 3:
                this.setState({ camState: 3 })
                this.catchPhoto()
                this.closeCamera()
                break;
        }
    }

    // 打开摄像头
    openCamera = () => {
        console.log(`open camera...`)
        const video = this.refs.video
        const videoObj = {
            video: {
                width: 320,
                height: 240
            }
        }
        const errBack = function (error) {
            console.log(error.message);
            console.log("Video capture error: ", error.message + " " + error.code);
        }

        // 判断媒体对象是否有权限
        if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
            navigator.mediaDevices.getUserMedia(videoObj).then(function (stream) {
                console.log(`video`, video)
                video.srcObject = trackStrem = stream
                video.play()
            }).catch(function (err) {
                errBack(err)
            })
        }
        else window.alert('打开摄像头失败')
        
    }

    // 关闭摄像头
    closeCamera = () => {
        console.log(`close camera...`)
        if (this.refs.video) this.refs.video.pause();
        if (trackStrem) trackStrem.getTracks()[0].stop();
    }

    // 保存图片
    catchPhoto = () => {
        const { onChange } = this.props;
        const canvas = this.refs.canvas
        const video = this.refs.video
        let context = canvas.getContext("2d")
        context.drawImage(video, 0, 0, 320, 240);
        // 从画布上获取照片数据
        let imgData = canvas.toDataURL(`image/jpeg`);
        // 对外派发图片数据
        if (onChange) onChange(imgData)
    }

    render() {
        const { camState } = this.state
        const { image } = this.props;

        console.log(`camState`, camState)

        return (
            <Row>
                <Col span={24} style={{ padding: 12, textAlign: 'center' }}>
                    <img style={{ width: 320, height: 240, display: camState === 1 ? 'block' : 'none' }} src={image} />
                    {/* <img alt="avatar" src={avatar} style={{ zIndex: 100, position: 'absolute', x: 0, y: 0, display: camState === 1 ? 'none' : 'block' }} /> */}
                    <video ref="video" width="320" height="240" autoPlay style={{ display: camState === 1 ? 'none' : 'block' }}></video>
                    <canvas ref="canvas" width="320" height="240" style={{ display: 'none' }}></canvas>
                </Col>
                <Col span={24} style={{ padding: 12, textAlign: 'center' }}>
                    {camState === 2 ? <Button onClick={() => this.changeState(3)} type="primary">保存快照</Button> : <Button onClick={() => this.changeState(2)} type="primary">重新拍照</Button>}
                </Col>
            </Row>
        );
    }
}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值