實現思路
-
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@Overridepublic 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獲取圖片信息、用畫筆畫出來@Overridepublic 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);}}}