一、简介
JavaCV使用来自计算机视觉领域(OpenCV, FFmpeg, libdc1394, PGR FlyCapture, OpenKinect, librealsense, CL PS3 Eye Driver, videoInput, ARToolKitPlus, flandmark, Leptonica, and Tesseract)领域的研究人员常用库的JavaCPP预设的封装。提供实用程序类,使其功能更易于在Java平台上使用,包括Android。
二、案例1:调用摄像头
(1)使用IDEA新建Maven项目,然后在pom.xml中引入下列依赖(因为要用到opencv来实现,所以需要引入opencv-platform包,此包会自动引入各大平台的依赖jar(内含dll)):
```java
```java
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/opencv-platform -->
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv-platform</artifactId>
<version>3.4.1-1.4.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
(2)测试类
import org.bytedeco.javacv.*;
import org.junit.Test;
import javax.swing.*;
import java.util.EnumSet;
public class JavaCVTest {
@Test
public void testCamera() throws InterruptedException, FrameGrabber.Exception {
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
grabber.start(); //开始获取摄像头数据
CanvasFrame canvas = new CanvasFrame("摄像头");//新建一个窗口
canvas.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
canvas.setAlwaysOnTop(true);
while (true) {
if (!canvas.isDisplayable()) {//窗口是否关闭
grabber.stop();//停止抓取
System.exit(-1);//退出
}
Frame frame = grabber.grab();
canvas.showImage(frame);//获取摄像头图像并放到窗口上显示, 这里的Frame frame=grabber.grab(); frame是一帧视频图像
Thread.sleep(50);//50毫秒刷新一次图像
}
}
@Test
public void testCamera1() throws FrameGrabber.Exception, InterruptedException {
VideoInputFrameGrabber grabber = VideoInputFrameGrabber.createDefault(0);
grabber.start();
CanvasFrame canvasFrame = new CanvasFrame("摄像头");
canvasFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
canvasFrame.setAlwaysOnTop(true);
while (true) {
if (!canvasFrame.isDisplayable()) {
grabber.stop();
System.exit(-1);
}
Frame frame = grabber.grab();
canvasFrame.showImage(frame);
Thread.sleep(30);
}
}
}
第二种方法 前端获取摄像头拍照功能实例
<template>
<div class="publish">
<video ref="video"></video>
<canvas style="display: none" id="canvasCamera"></canvas>
<div v-if="imgSrc" class="img_bg_camera">
<img :src="imgSrc" class="tx_img" />
</div>
<button @click="OpenCamera">打开摄像头</button>
<button @click="CloseCamera">关闭摄像头</button>
<button @click="setImage">拍照</button>
</div>
</template>
<script>
export default {
data() {
return {
mediaStreamTrack: {},
video_stream: '', // 视频stream
imgSrc: '', // 拍照图片
canvas: null,
context: null,
};
},
mounted() {
// 进入页面 自动调用摄像头
this.getCamera();
},
methods: {
// 调用打开摄像头功能
getCamera() {
// 获取 canvas 画布
this.canvas = document.getElementById('canvasCamera');
this.context = this.canvas.getContext('2d');
// 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
// 正常支持版本
navigator.mediaDevices
.getUserMedia({
video: true,
})
.then((stream) => {
// 摄像头开启成功
this.mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[0];
this.video_stream = stream;
this.$refs.video.srcObject = stream;
this.$refs.video.play();
})
.catch(err => {
console.log(err);
});
},
// 拍照 绘制图片
setImage() {
console.log('拍照');
// 点击canvas画图
this.context.drawImage(
this.$refs.video,
0,
0,
200,
100,
);
// 获取图片base64链接
const image = this.canvas.toDataURL('image/png');
this.imgSrc = image;
this.$emit('refreshDataList', this.imgSrc);
},
// 打开摄像头
OpenCamera() {
console.log('打开摄像头');
this.getCamera();
},
// 关闭摄像头
CloseCamera() {
console.log('关闭摄像头');
this.$refs.video.srcObject.getTracks()[0].stop();
},
},
};
</script>
<style lang="less" scoped>
video {
width: 100%;
height: 300px;
}
canvas {
width: 100%;
height: 300px;
}
button {
width: 100px;
height: 40px;
position: relative;
bottom: 0;
left: 0;
background-color: rgb(22, 204, 195);
}
.img_bg_camera {
img {
width: 300px;
height: 200px;
}
}
</style>
录像功能实例
<template>
<div class="publish">
<!-- 下载按钮 -->
<a id="downLoadLink" style="display: none;"></a>
<video ref="video"></video>
<!-- 视频录制或暂停 -->
<div @click="recordOrStop">视频录制</div>
</div>
</template>
<script>
export default {
data() {
return {
mediaStreamTrack: {}, // 退出时关闭摄像头
video_stream: '', // 视频stream
recordedBlobs: [], // 视频音频 blobs
isRecord: false, // 视频是否正在录制
};
},
mounted() {
// 进入页面 调用摄像头
this.getCamera();
},
methods: {
// 调用打开摄像头功能
getCamera() {
// 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
navigator.mediaDevices
.getUserMedia({
video: true,
})
.then((stream) => {
// 摄像头开启成功
this.mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[0];
this.video_stream = stream;
this.$refs.video.srcObject = stream;
this.$refs.video.play();
})
.catch(err => {
console.log(err);
});
},
// 录制或暂停
recordOrStop() {
if (this.isRecord) {
this.stop();
} else {
this.record();
}
},
// 视频录制
record() {
console.log('record');
this.isRecord = !this.isRecord;
let mediaRecorder;
let options;
this.recordedBlobs = [];
if (typeof MediaRecorder.isTypeSupported === 'function') {
// 根据浏览器来设置编码参数
if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
options = {
MimeType: 'video/webm;codecs=h264',
};
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) {
options = {
MimeType: 'video/webm;codecs=h264',
};
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
options = {
MimeType: 'video/webm;codecs=vp8',
};
}
mediaRecorder = new MediaRecorder(this.video_stream, options);
} else {
// console.log('isTypeSupported is not supported, using default codecs for browser');
console.log('当前不支持isTypeSupported,使用浏览器的默认编解码器');
mediaRecorder = new MediaRecorder(this.video_stream);
}
mediaRecorder.start();
// 视频录制监听事件
mediaRecorder.ondataavailable = e => {
console.log(e);
// 录制的视频数据有效
if (e.data && e.data.size > 0) {
this.recordedBlobs.push(e.data);
}
};
// 停止录像后增加下载视频功能,将视频流转为mp4格式
mediaRecorder.onstop = () => {
const blob = new Blob(this.recordedBlobs, { type: 'video/mp4' });
this.recordedBlobs = [];
// 将视频链接转换完可以用于在浏览器上预览的本地视频
const videoUrl = window.URL.createObjectURL(blob);
// 设置下载链接
document.getElementById('downLoadLink').href = videoUrl;
// 设置下载mp4格式视频
document.getElementById('downLoadLink').download = 'media.mp4';
document.getElementById('downLoadLink').innerHTML = 'DownLoad video file';
// 生成随机数字
const rand = Math.floor((Math.random() * 1000000));
// 生成视频名
const name = `video${rand}.mp4`;
// setAttribute() 方法添加指定的属性,并为其赋指定的值
document.getElementById('downLoadLink').setAttribute('download', name);
document.getElementById('downLoadLink').setAttribute('name', name);
// 0.5s后自动下载视频
setTimeout(() => {
document.getElementById('downLoadLink').click();
}, 500);
};
},
// 停止录制
stop() {
this.isRecord = !this.isRecord;
if (!this.$refs.video.srcObject) return;
const stream = this.$refs.video.srcObject;
const tracks = stream.getTracks();
// 关闭摄像头和音频
tracks.forEach(track => {
track.stop();
});
},
},
};
</script>
<style lang="less" scoped>
.publish {
color: #fff;
video {
width: 100%;
height: 100vh;
}
div {
position: absolute;
left: calc(50% - 80px);
bottom: 0;
height: 40px;
width: 160px;
font-size: 14px;
border-radius: 10px;
line-height: 40px;
background-color: rgb(25, 179, 179);
text-align: center;
}
}
</style>