提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
使用webcam-capture实现调用电脑摄像头,并运用多线程实现摄像头的启动、关闭以及拍照。
webcam-capture为github的开源项目 http://webcam-capture.sarxos.pl/
一、导入webcam-capture包
1.在网站上下载压缩包。
2.解压后找到三个jar文件。
3.在自己的项目中创建一个lib,将三个jar文件放入。
4.将三个文件全选,右键添加为库。
导包完成
二、显示相机界面
需要创建窗体,添加按钮,设置按钮监听器
package test;
import javax.swing.*;
import java.awt.*;
public class test1VideoCapture extends JFrame {
//创建监听器
VCListener vcl=new VCListener();
public void initUI(){
//创建窗口
setTitle("Video Capture");
setSize(1200,800);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
//添加按钮
String[] str={"启动","关闭","拍照"};
for (String strs:str){
JButton btn=new JButton(strs);
btn.setPreferredSize(new Dimension(90,30));
btn.addActionListener(vcl);
add(btn);
}
//可视化
setVisible(true);
vcl.setG(getGraphics());
}
//main方法
public static void main(String[] args) {
new test1VideoCapture().initUI();
}
}
三、完成监听器
加载摄像头
webcam = Webcam.getDefault ();
启动摄像头
webcam.open ();
通过循环使摄像头显示动画,当图片加载速度大于24FPS时,就能够看到动画
package test;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamUtils;
import com.github.sarxos.webcam.util.ImageUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
public class VCListener implements ActionListener{
private Graphics g = null;
public void setGraphics(Graphics g){
this.g = g;
}
Webcam webcam=null;
RunVideoAble rvt=null;
boolean flag = false;
@Override
public void actionPerformed(ActionEvent e){
String str = e.getActionCommand ();
if(str.equals ("启动")){
// 加载摄像头
webcam = Webcam.getDefault ();
// 启动
webcam.open ();
flag = true;
// 分支任务
while(flag){
BufferedImage image = webcam.getImage ();
g.drawImage (image, 50, 50, null);
}
}else if(str.equals ("关闭")){
flag=false;
}else if(str.equals ("拍照")){
//在这里先省略
}
}
}
写到这里可以试一下点击启动按钮,发现整个窗口无法实现其他功能了。由此引入多线程
四、多线程简介
一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。
这里定义和线程相关的另一个术语 - 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程。一个线程不能独立的存在,它必须是进程的一部分。一个进程一直运行,直到所有的非守护线程都结束运行后才能结束。
多线程能满足程序员编写高效率的程序来达到充分利用 CPU 的目的。
引用自https://www.runoob.com/java/java-multithreading.html
通过Runnable 接口创建线程
public void run()
可以重写该方法,调用其他方法,使用其他类,并声明变量
@Override
public class RunVideoThread implements Runnable{
public void run(){
//分支任务
while(flag){
BufferedImage image=webcam.getImage();
g.drawImage(image,100,50,null);
}
}
Thread 类 : Thread: 整个线程的管理类,管理线程的生命周期,负责启动、运行、停止等
继承类如下
package test;
import com.github.sarxos.webcam.Webcam;
import java.awt.*;
import java.awt.image.BufferedImage;
public class RunVideoThread implements Runnable{
boolean flag;
Webcam webcam;
Graphics g;
public RunVideoThread(Webcam webcam, Graphics g) {
this.webcam = webcam;
this.g = g;
}
public void open(){
flag=true;
}
public void close(){
flag=false;
}
@Override
public void run(){
//分支任务
while(flag){
BufferedImage image=webcam.getImage();
g.drawImage(image,100,50,null);
}
}
}
新线程创建之后,要调用它的 start() 方法它才会运行。所以要修改监听器类
改后监听器类如下
package test;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamUtils;
import com.github.sarxos.webcam.util.ImageUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
public class VCListener implements ActionListener {
private Graphics g=null;
Webcam webcam=null;
boolean flag=false;
RunVideoThread rvt=null;
private JPanel showPanel;
public void setG(Graphics g){
this.g=g;
}
public void actionPerformed(ActionEvent e){
String str=e.getActionCommand();
if(str.equals("启动")){
flag=true;
webcam= Webcam.getDefault();
webcam.open();
rvt=new RunVideoThread(webcam,g);
rvt.open();
Thread t=new Thread(rvt);
t.start();
}else if (str.equals("关闭")){
webcam.close();
rvt.close();
} else if (str.equals("拍照")) {
}
}
}
五、实现拍照
可以用IO流的方式,也可以用Swing线程
先String 文件名,可以命名为String fileName="D://"+System.currentTimeMillis();
名字为拍照时的时间。
然后捕获图像
WebcamUtils.capture(webcam,fileName, ImageUtils.FORMAT_PNG);
最后用Swing线程(这个笔者不是很懂,是在网上查的)
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JOptionPane.showConfirmDialog(null,"拍照成功");
}
});
参考
https://blog.youkuaiyun.com/bzwm/article/details/3895381#:~:text=%E8%A7%A3%E9%87%8A%EF%BC%9ASwing,%E5%8F%AF%E8%BF%90%E8%A1%8C%E5%AF%B9%E8%B1%A1%E6%8E%92%E9%98%9F%E3%80%82
完整监听器类如下
package test;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamUtils;
import com.github.sarxos.webcam.util.ImageUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
public class VCListener implements ActionListener {
private Graphics g=null;
Webcam webcam=null;
boolean flag=false;
RunVideoThread rvt=null;
private JPanel showPanel;
public void setG(Graphics g){
this.g=g;
}
public void actionPerformed(ActionEvent e){
String str=e.getActionCommand();
if(str.equals("启动")){
flag=true;
webcam= Webcam.getDefault();
webcam.open();
rvt=new RunVideoThread(webcam,g);
rvt.open();
Thread t=new Thread(rvt);
t.start();
}else if (str.equals("关闭")){
webcam.close();
rvt.close();
} else if (str.equals("拍照")) {
String fileName="D://"+System.currentTimeMillis();
WebcamUtils.capture(webcam,fileName, ImageUtils.FORMAT_PNG);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JOptionPane.showConfirmDialog(null,"拍照成功");
}
});
}
}
}