实现思路
-
0,将webcam的jar文件传入项目中
-
1,显示摄像头的地方:创建一个画板,在画板上添加开启和关闭按钮
-
2,设置开启和关闭功能:创建一个类实现动作监听器,进而实现监听动作按钮
-
3,实现开启和关闭操作:创建一个类继承或实现线程,使得可以同步实现多线程
-
4,保存拍照的图片:执行一次Webcam的打开、通过IO流传入文件夹中
显示摄像头的地方-画板类继承JFrame
- 创建显示方法:设置标题、大小、居中、默认退出、可见(放在最后)
- 添加按钮:创建按钮数组、遍历按钮数组(创建按钮对象把遍历后的按钮传入、设置按钮大小、添加动作监听器、把按钮添加到窗体)
- 在主方法中创建对象调用显示方法
设置开启和关闭功能-实现动作监听器
- 重写监听器的方法actionPerformed:获取动作监听器传过来的指令、对指令进行判断进行相应的操作
- 创建画笔:创建画笔对象,通过画笔来画出图像、创建画笔的set对象,用来获得画板类传过来的画笔
- 在画板类中创建监听器对象:将监听器对象传入按钮中、调用监听器对象中的set方法,将画板类的画笔传入
实现开启和关闭操作-继承Thread,实现多线程同步
- 添加画笔
- 添加webcam和画笔g的构造器:使得可以将将构造器中的webcam和画笔g传进来
- 重写run方法:设置while循环,使webcam调用getImage获取图片信息、用画笔画出来
- 创建Open和Close方法,对run方法中的while循环进行控制
保存拍照的图片
- 创建方法actPicture用于进行拍照
- 创建方法savePicture用于往文件中传照片
- 在actPicture方法中调用savePicture方法,并传入拍的照片
复制图片-使用处理流:bufferedInputStream1和BufferedOutputStream
- 1,定义被复制和复制后的路径
- 2,创建处理流对象,将路径传入
- 3,读取文件到byte类型的数组中
- 4,当buff的值为-1时,停止复制
- 5,判断当处理流不为空时关闭处理流
代码
窗体类
import javax.swing.*;
import java.awt.*;
/*怎么在一个界面添加监听器
1,创建继承了监听器的类对象
2,把这个对象传给按钮
*/
public class Viedio extends JFrame {
//新建一个监听器对象
VCLlistener vcLlistener = new VCLlistener();
//创建显示方法
public void initUI() {
setTitle("摄像头");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setSize(1000, 800);
setLayout(new FlowLayout());
//添加按钮
String[] s = {"开启", "关闭"};
for (String str : s) {
JButton jButton = new JButton(str);
jButton.setPreferredSize(new Dimension(85, 35));
//将监听器对象传入按钮中
jButton.addActionListener(vcLlistener);
add(jButton);
}
setVisible(true);
vcLlistener.setG(getGraphics());
}
//在主方法中创建对象调用显示方法
public static void main(String[] args) {
new Viedio().initUI();
}
}
接口类
import com.github.sarxos.webcam.Webcam;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
/*怎么创建监听器
1,创建一个类实现监听器接口
2,重写监听器的方法
3,在方法中编辑我们要实现的功能
*/
public class VCLlistener implements ActionListener {
Graphics g;
Webcam webcam;
//创建画笔的set对象,用来获得画板类传过来的画笔
public void setG(Graphics g) {
this.g = g;
}
boolean tool = true;
//重写监听器的方法actionPerformed
@Override
public void actionPerformed(ActionEvent e) {
//获取动作监听器传过来的指令
String str = e.getActionCommand();
if (str.equals("开启")) {
webcam = Webcam.getDefault();
webcam.open();
VideoThread videoThread = new VideoThread(webcam, g);
videoThread.Open();
videoThread.start();
} else if (str.equals("关闭")) {
VideoThread videoThread = new VideoThread(webcam, g);
videoThread.Close();
webcam.close();
}
}
}
线程类
import com.github.sarxos.webcam.Webcam;
import java.awt.*;
import java.awt.image.BufferedImage;
public class VideoThread extends Thread{
boolean flag = true;
Webcam webcam = null;
Graphics g =null;
//添加webcam和画笔g的构造器:使得可以将将构造器中的webcam和画笔g传进来
public VideoThread(Webcam webcam, Graphics g) {
this.webcam = webcam;
this.g = g;
}
//创建Open和Close方法,对run方法中的while循环进行控制
public void Open(){
flag = true;
}
public void Close(){
flag = false;
}
//重写run方法:设置while循环,使webcam调用getImage获取图片信息、用画笔画出来
@Override
public void run() {
while (flag){
BufferedImage image = webcam.getImage();
g.drawImage(image, 50, 50, null);
}
}
}
保存照片
//拍照并保存
public void actPicture() {
Webcam webcam = Webcam.getDefault();
// if (webcam != null) {
webcam.open();
// 等待相机准备好
try {
Thread.sleep(1000); // 等待1秒钟以确保相机已准备好
} catch (InterruptedException e) {
e.printStackTrace();
}
BufferedImage image = webcam.getImage();
g.drawImage(image, 400, 400, null);
savePicture(image);
// }else {
// System.out.println("未检测到摄像头");
// }
}
//拍照 存到文件夹中
public void savePicture(BufferedImage bi) {
try {
//创建文件对象:保存图片要通过文件来保存,最好不用BufferOutputStream,因为是要将图像保存到文件夹中,而不是字符流
File output = new File("D:\\photo\\output.png");
//用图像IO流去调用write方法写出到文件中
ImageIO.write(bi, "png", output);
System.out.println("保存成功");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
复制图片-最后调用copyPictere方法即可
//复制图片
//1,定义被复制和复制后的路径
String path = "D:\\photo\\output.png";
String path1 = "D:\\photo1\\output.png";
BufferedOutputStream bufferedOutputStream;
BufferedInputStream bufferedInputStream1;
public void copyPictere() {
try {
//2,创建处理流对象,将路径传入
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(path1));
bufferedInputStream1 = new BufferedInputStream(new FileInputStream(path));
//3,读取文件到byte类型的数组中
byte[] buff = new byte[1024];
int readLen = 0;
//4,当buff的值为-1时,停止复制
while ((readLen = bufferedInputStream1.read(buff)) != -1) {
bufferedOutputStream.write(buff, 0, readLen);
}
System.out.println("复制完毕");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//5,判断当处理流不为空时关闭处理流
if (bufferedInputStream1 != null) {
bufferedInputStream1.close();
}
if (bufferedOutputStream != null) {
bufferedOutputStream.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}