java调用电脑摄像头


import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.VideoWriter;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CameraCapture {

// 加载 OpenCV native
static {
try {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
} catch (UnsatisfiedLinkError e) {
System.err.println("加载 OpenCV 库失败:" + e.getMessage());
System.exit(1);
}
}

private JFrame frame;
private JLabel imageLabel;
private JButton btnCapture;
private JButton btnRecord;
private VideoCapture capture;
private VideoWriter writer;
private boolean recording = false;
private Size frameSize;
private final int fourcc = VideoWriter.fourcc('M', 'J', 'P', 'G'); // 使用 MJPG 编码
private final int fps = 20; // 帧率

public CameraCapture() {
initGUI();
startCamera();
}

// 初始化图形界面
private void initGUI() {
frame = new JFrame("摄像头拍照录像");
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// JLabel 显示视频画面
imageLabel = new JLabel();
frame.add(imageLabel, BorderLayout.CENTER);

// 底部面板放置拍照与录像按钮
JPanel panel = new JPanel();
btnCapture = new JButton("拍照");
btnRecord = new JButton("开始录像");
panel.add(btnCapture);
panel.add(btnRecord);
frame.add(panel, BorderLayout.SOUTH);

// 拍照按钮事件
btnCapture.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
capturePhoto();
}
});

// 录像按钮事件:点击开始或停止录像
btnRecord.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
toggleRecording();
}
});

frame.setSize(800, 600);
frame.setVisible(true);
}

// 启动摄像头并在后台线程中捕获视频帧
private void startCamera() {
capture = new VideoCapture(0);
if (!capture.isOpened()) {
System.err.println("无法打开摄像头,请检查摄像头是否正常连接或被其他程序占用!");
System.exit(1);
}

// 获取第一帧来确定视频尺寸
Mat tempMat = new Mat();
capture.read(tempMat);
frameSize = new Size(tempMat.width(), tempMat.height());

// 新线程中循环读取摄像头帧
Thread cameraThread = new Thread(() -> {
Mat frameMat = new Mat();
while (capture.isOpened()) {
if (capture.read(frameMat)) {
// 如果正在录像,写入当前帧到视频文件
if (recording && writer != null) {
writer.write(frameMat);
}
// Mat 转换为 BufferedImage 并显示
ImageIcon image = new ImageIcon(matToBufferedImage(frameMat));
imageLabel.setIcon(image);
imageLabel.repaint();
}
try {
Thread.sleep(33); // 大约 30 /
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
cameraThread.start();
}

// 拍照:捕获当前帧并保存为 PNG 图片
private void capturePhoto() {
Mat frameMat = new Mat();
if (capture.read(frameMat) && !frameMat.empty()) {
String filename = "photo_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".png";
if (Imgcodecs.imwrite(filename, frameMat)) {
System.out.println("已保存照片: " + filename);
} else {
System.err.println("保存照片失败");
}
} else {
System.err.println("未捕获到有效的视频帧,拍照失败");
}
}

// 切换录像状态:开始录像或停止录像
private void toggleRecording() {
if (!recording) {
// 开始录像,初始化 VideoWriter
String filename = "video_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".avi";
writer = new VideoWriter(filename, fourcc, fps, frameSize, true);
if (!writer.isOpened()) {
System.err.println("无法初始化录像设备!");
return;
}
recording = true;
btnRecord.setText("停止录像");
System.out.println("开始录像: " + filename);
} else {
// 停止录像,释放 VideoWriter
recording = false;
if (writer != null) {
writer.release();
writer = null;
}
btnRecord.setText("开始录像");
System.out.println("停止录像");
}
}

// OpenCV Mat 对象转换为 Java BufferedImage 以便在 Swing 中显示
private BufferedImage matToBufferedImage(Mat mat) {
int type = BufferedImage.TYPE_BYTE_GRAY;
if (mat.channels() > 1) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = mat.channels() * mat.cols() * mat.rows();
byte[] buffer = new byte[bufferSize];
mat.get(0, 0, buffer); // 复制像素数据到数组中
BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), type);
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(buffer, 0, targetPixels, 0, buffer.length);
return image;
}

// 主方法:在 Swing 的事件分发线程中启动应用
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new CameraCapture());
}
}


<dependencies>
<dependency>
<groupId>org.opencv</groupId>
<artifactId>opencv</artifactId>
<version>4.11.0</version>
<scope>system</scope>
<systemPath>C:\Users\s\Documents\untitled3\libs\opencv-4110.jar</systemPath>
</dependency>
</dependencies>
 
-Djava.library.path="C:\Users\s\Downloads\opencv\build\java\x64"



posted on   shenhshihao  阅读(17)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
历史上的今天:
2022-02-04 怎么用pr制作消融转场效果

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示