前期系统中需要使用照相功能,在百度和同事的帮助下做出了一个简易版的项目,最近有时间整理一下,分享出来。
这个项目实现起来也不是很复杂,不过所依赖的核心jar包比较大,我创建的是一个普通java project,没有创建maven工程,也可以使用maven,不过会引入大量使用不到的jar包。这个项目我已经放到GitHub上面了,文章末尾会给出地址,依赖的pom文件会一起放在项目中,方便查找。
1.项目结构:
项目使用java的图形界面编程,需要一定的基础,不过也不是很难,主要是几个Listener的编写,TuPianJieQuActionListener是保存文件的主要监听类。2.jar包:
使用log4j-1.2.17.jar记录日志,commons-codec-1.13.jar是用来进行BASE64编码的,thumbnailator-0.4.8.jar可以便捷的实现图片压缩,其他的基本都是照相的核心jar包,如果使用maven创建会多出很多不需要的jar包,需要注意一下。
3.TakePhoto照相核心类的实现:
/**
*
* @author jinghuaixin
* @date 2019/11/28
*/
public class TakePhoto {
private static OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
private static CanvasFrame canvas = null;
private static Map<String, Object> map;
public static void main(String[] args) {
try {
takePhoto();
} catch (Exception | InterruptedException e) {
e.printStackTrace();
LogUtil.getLog().error("客户端照相异常!", e);
}
}
public static void takePhoto() throws Exception, InterruptedException {
int captureWidth = 640;
int captureHeight = 480;
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
grabber.setImageWidth(captureWidth);
grabber.setImageHeight(captureHeight);
try {
grabber.start();
} catch (Exception e) {
LogUtil.getLog().error("照相客户端初始化异常!", e);
JOptionPane.showMessageDialog(null, "摄像头准备失败:请检查摄像头是否正确接入!", "提示:", JOptionPane.WARNING_MESSAGE);
if (grabber != null) {
grabber.close();
}
return;
}
// 开始获取摄像头数据
canvas = new CanvasFrame("照相");
// CanvasFrame canvas = new CanvasFrame("照相");//新建一个窗口
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvas.setAlwaysOnTop(true);
Camera camera = new Camera();
MyPanel shangChuanPanel = new MyPanel(canvas, map);
// 增加按钮
Container con = canvas.getContentPane();
JPanel optionPanel = new JPanel();
JButton btn_paiZhao = new JButton("拍照");
JButton btn_chongPai = new JButton("重拍");
JButton btn_guanBi = new JButton("关闭");
JLabel info = new JLabel("<html><font color='red'>(连接成功!)</font></html>");
JPanel bott = new JPanel();
// 向面板添加按钮
optionPanel.add(btn_chongPai, BorderLayout.NORTH);
optionPanel.add(btn_paiZhao, BorderLayout.NORTH);
optionPanel.add(btn_guanBi, BorderLayout.NORTH);
con.add(optionPanel, BorderLayout.NORTH);
bott.add(info, BorderLayout.SOUTH);
con.add(bott, BorderLayout.SOUTH);
JPanel east = new JPanel();
east.setSize(new Dimension(600, 600));
JLabel eastlabel = new JLabel(getSapce(220));
if (shangChuanPanel != null) {
east.add(shangChuanPanel, BorderLayout.SOUTH);
shangChuanPanel.add(eastlabel);
con.add(shangChuanPanel, BorderLayout.EAST);
}
// 添加监听事件
PaiZhaoMouseListener pzListener = new PaiZhaoMouseListener(converter, grabber, camera, shangChuanPanel);
btn_paiZhao.addMouseListener(pzListener);
btn_guanBi.addMouseListener(new GuanBiMouseListener(canvas));
btn_chongPai.addMouseListener(new ChongPaiMouseListener(camera));
Frame grab = grabber.grab();
shangChuanPanel.setMat(converter.convertToMat(grab));
while (true) {
if (!canvas.isDisplayable()) {// 窗口是否关闭
grabber.stop();// 停止抓取
// System.exit(2);//退出
break;
}
if (camera.getState()) {
grab = grabber.grab();// 获取摄像头图像并放到窗口上显示, 这里的Frame frame=grabber.grab(); frame是一帧视频图像
}
if (grab != null) {
canvas.showImage(grab);
}
Thread.sleep(50);// 50毫秒刷新一次图像
}
}
/**
* 扩展canvasFrame的右边空间
*
* @param count
* @return
*/
public static String getSapce(int count) {
count = count < 0 ? 0 : count;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
sb.append(" ");
}
return sb.toString();
}
/**
* @return the canvas
*/
public static CanvasFrame getCanvas() {
return canvas;
}
}
4.设备:
实现照相你需要一个照相设备,使用USB摄像头就可以。
5.项目演示:
运行main方法,弹出拍照页面:
点击拍照按钮进行图片拍照,点击重拍按钮可以重新拍摄
红色方框可拖动,用于截取照片,选中合适的区域双击即可实现类似于截图的功能
现在看到的就是剪切以后的图片,点击上传即可保存到本地,上传按钮是因为实际应用中该项目使用WebSocket实现与浏览器通信,实现上传效果
保存后关闭页面去项目地址下即可发现刚刚的截图