그래서 왼쪽에다 버튼 붙이고, 각 이미지 프로세싱을 위한 기능을 두 개 살펴 본 것 같습니다.
그런 다음은 동영상이 아닐까 하는 데요.
동영상은 오히려 쉽지 않을까 하는 생각이 왠지 드네요
우선 카메라 켜는 버튼 밖에 없으니까 옆에다가
- 버튼 하나 만들고 'go clip' 해 볼까요?
- 이 'go clip' 버튼을 누르면 동영상을 하나 선택 하면 좋을 거예요
- 동영상을 선택하면, 카메라 영상 나오는 위치에 동영상을 틀면
될 것 같아요~ 모양은 이렇게
그럼 갑자기 이렇게 된 거, 이미지 로딩 버튼도 만들어 보아요~
'go image' 좋으네요
아래 처럼...🤤
private void initCamPanel(final boolean isCanvas) {
setLayout(new BorderLayout());
JPanel btnPane = new ButtonPanel();
JPanel btnCtrlPane = new JPanel();
btnCtrlPane.add(goCam);
btnCtrlPane.add(goClip);
btnCtrlPane.add(goImage);
if (!isCanvas) {
camPane.setSize(new Dimension(600, 450));
camPane.setPreferredSize(new Dimension(600, 450));
add(camPane, BorderLayout.CENTER);
add(btnCtrlPane, BorderLayout.SOUTH);
add(btnPane, BorderLayout.WEST);
goCam.setActionCommand("goCamPanel");
goClip.setActionCommand("goClipPanel");
goImage.setActionCommand("goImagePanel");
} else {
camCavs.setSize(new Dimension(600, 450));
camCavs.setPreferredSize(new Dimension(600, 450));
add(camCavs, BorderLayout.CENTER);
add(btnCtrlPane, BorderLayout.SOUTH);
add(btnPane, BorderLayout.WEST);
goCam.setActionCommand("goCamCanvas");
goClip.setActionCommand("goClipCanvas");
goImage.setActionCommand("goImageCanvas");
}
goCam.addActionListener(btnListener);
}
그럼, 이런 모양이 되겠죠?
그런데 뭐 클립 보다는 비디오가 나을 듯 해서 'Go video~' 가 나을 것 같으네요
그럼 그렇게 다시 정하는 것으로 합니다.
그럼 액션리스너를 MainButtonClickListener 로 바꾸어야 한다고 봅니다
class MainButtonClickListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("goCamPanel")) {
camPane.startCamera();
} else if (e.getActionCommand().equals("goCamCanvas")) {
camCavs.startCamera();
}else if (e.getActionCommand().equals("goMoviePanel")) {
// 코드를 넣어야 해요~
}else if (e.getActionCommand().equals("goMovieCanvas")) {
// 코드를 넣어야 해요~
}else if (e.getActionCommand().equals("goImagePanel")) {
// 코드를 넣어야 해요~
}else if (e.getActionCommand().equals("goImageCanvas")) {
// 코드를 넣어야 해요~
}
}
}
이젠 정말 코드를 넣어야 해요~ 코드를 넣기 위해선 이런 클래스들이 있으면 해서 만들었습니다.
이렇게(🤔~)
private static MoviePanel moviePane = new MoviePanel();
private static ImagePanel imagePane = new ImagePanel();
private static MovieCanvas movieCanvas = new MovieCanvas();
private static ImageCanvas imageCanvas = new ImageCanvas();
MoviePanel은 CamPanel과 비슷하겠죠?
MovieCanvas는 CamCanvas 랑 비슷 할 것이구요~~
그렇게 생각해 보면 InnerUtil 클래스의 openCam과 isCamOpened 메서드를 약간 변경 하면 될 것 같아요...
static void openMovie(String moviepath) {
capture.open(moviepath);
}
static boolean isMovieOpened() {
return capture.isOpened();
}
모든 것이 거의 복 붙 수준이니까. 위 메서드를 사용 할 클래스 중 하나만 본다면,
final static class CamCanvasDubleBuffer extends Canvas {
private static final long serialVersionUID = 1235525630469980081L;
// a flag to change the button behavior
private boolean cameraActive = false;
private BufferedImage bufImagew;
// for duble buffering...
@Override
public void update(Graphics g) {
Graphics2D g2;
g2 = (Graphics2D) g;
Graphics offgc;
Image offscreen;
if (bufImagew != null) {
offscreen = createImage(bufImagew.getWidth(), bufImagew.getHeight());
offgc = offscreen.getGraphics();
// clear the exposed area
offgc.setColor(getBackground());
offgc.drawImage(bufImagew, 0, 0, getWidth(), getHeight(), null);
offgc.setColor(getBackground());
g2.drawImage(offscreen, 0, 0, getWidth(), getHeight(), null);
}
}
protected void startCamera() {
if (!this.cameraActive) {
// start the video capture
InnerUtil.openCam();
// is the video stream available?
if (InnerUtil.isCamOpened()) {
cameraActive = true;
// grab a frame every 33 ms (30 frames/sec)
Runnable frameGrabber = new Runnable() {
@Override
public void run() {
// effectively grab and process a single frame
Mat frame = InnerUtil.grabFrame();
// convert and show the frame
bufImagew = Utils.matToBufferedImage(frame);
repaint();
}
};
InnerUtil.scheduleStart(frameGrabber);
// update the button content
goCam.setText("Stop Camera");
} else {
// log the error
System.err.println("Impossible to open the camera connection...");
}
} else {
// the camera is not active at this point
this.cameraActive = false;
// update again the button content
goCam.setText("Start Camera");
// stop the timer
InnerUtil.stopAcquisition();
}
}
protected void startCamera(int drawingStyle) {
startCamera(drawingStyle, null);
}
protected void startCamera(int drawingStyle, CannyOption cannyOpt) {
if (this.cameraActive) {
// is the video stream available?
if (InnerUtil.isCamOpened()) {
cameraActive = true;
// grab a frame every 33 ms (30 frames/sec)
Runnable frameGrabber = new Runnable() {
@Override
public void run() {
// effectively grab and process a single frame
Mat frame = InnerUtil.grabFrame(drawingStyle, cannyOpt);
// convert and show the frame
bufImagew = Utils.matToBufferedImage(frame);
// System.out.println("3 " + bufImagew.getWidth() + ":" + bufImagew.getWidth());
// updateImageView(currentFrame, imageToShow);
repaint();
// invalidate();
}
};
InnerUtil.scheduleStart(frameGrabber);
// update the button content
goCam.setText("Stop Camera");
} else {
// log the error
System.err.println("Impossible to open the camera connection...");
}
} else {
// the camera is not active at this point
this.cameraActive = false;
// update again the button content
goCam.setText("Start Camera");
// stop the timer
InnerUtil.stopAcquisition();
}
}
}
예쁘게 나왔네요~(😁~)
ImagePanel 이나 ImageCanvas 는 좀 있다가 생각 하는 것으로 하고
둘 다, 껍데기만 만들어 놓아요~
그런 다음, 액션리스너 인 MainButtonClickListener를 살짝 다음처럼 수정 합니다.
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("goCamPanel")) {
camPane.startCamera();
} else if (e.getActionCommand().equals("goCamCanvas")) {
camCavs.startCamera();
}else if (e.getActionCommand().equals("goMoviePanel")) {
String moviePath = movieGui();
moviePane.startMovie(moviePath);
}else if (e.getActionCommand().equals("goMovieCanvas")) {
String moviePath = movieGui();
movieCanvas.startMovie(moviePath);
}else if (e.getActionCommand().equals("goImagePanel")) {
imagePane.startImageProc("");
}else if (e.getActionCommand().equals("goImageCanvas")) {
imageCanvas.startImageProc();
}
}
movieGui 는 동영상 경로만 받으면 될꺼에요
이렇게~
private String movieGui() {
String moviePath = null;
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 0));
panel.setBackground(new Color(0, 0, 0));
panel.setSize(new Dimension(250, 100));
panel.setPreferredSize(new Dimension(250, 100));
// panel.setLayout(null);
JTextField txtMoviePath = new JTextField();
txtMoviePath.setForeground(new Color(0, 0, 0));
txtMoviePath.setHorizontalAlignment(SwingConstants.CENTER);
txtMoviePath.setFont(new Font("Arial", Font.BOLD, 11));
txtMoviePath.setBounds(0, 0, 250, 32);
JButton btnChooseMovie = new JButton("select movie");
btnChooseMovie.setForeground(new Color(0, 0, 0));
btnChooseMovie.setHorizontalAlignment(SwingConstants.CENTER);
btnChooseMovie.setFont(new Font("Arial", Font.BOLD, 11));
btnChooseMovie.setBounds(0, 0, 250, 32);
//JPanel MoviePane = new JPanel();
JLabel lblMoviePath = new JLabel("Movie Selection : Movie Path");
lblMoviePath.setForeground(new Color(255, 255, 255));
lblMoviePath.setHorizontalAlignment(SwingConstants.CENTER);
lblMoviePath.setFont(new Font("Arial", Font.BOLD, 11));
txtMoviePath.setSize(new Dimension(170, 25));
txtMoviePath.setPreferredSize(new Dimension(170, 25));
// panel.add(new JLabel("Low: "));
panel.add(lblMoviePath);
panel.add(txtMoviePath);
panel.add(btnChooseMovie);
UIManager.put("OptionPane.minimumSize", new Dimension(270, 120));
int result = JOptionPane.showConfirmDialog(HelloCamera.this, panel, "Select Movie",
JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
try {
moviePath = txtMoviePath.getText();
} catch (Exception ne) {
JOptionPane.showMessageDialog(null, "동영상이 설정이 안되면 진행 할 수 없어요!", "동영상 위치부족",
JOptionPane.INFORMATION_MESSAGE);
}
}
else
{
startCam(mIsCanvasDrawing, CANNY_DRAWING);
}
return moviePath;
}
그럼 아래 같은 사용자 입력 창이 뜨겠죠?
근데 버튼에다가 파일 다이얼로그를 붙혀야 하는 게 남았네요~(이러니 UI 작업은 누구나 싫어하죠..😭)
그건 이렇게 붙혀 볼까요?
btnChooseMovie.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
FileDialog fileDialogOpen = new FileDialog(mJFrame, "파일 열기", FileDialog.LOAD);
fileDialogOpen.setVisible(true);
String filePath = fileDialogOpen.getDirectory() == null ? "":fileDialogOpen.getDirectory() + fileDialogOpen.getFile() == null ? "":fileDialogOpen.getFile();
txtMoviePath.setText(filePath);
}
});
위에 껀 아래서 따다 썻서요
예상대로 라면... 이렇게 되겠죠?
예상대로 네요...
아닐 수도 있고~~~
오늘은 여기까지
'프로그래밍 > [Java] OpenCV' 카테고리의 다른 글
OpenCV와 자바 - 4.1. 이미지 조작 - 2 (0) | 2022.09.15 |
---|---|
OpenCV와 자바 - 4.1. 이미지 조작 - 1 (0) | 2022.09.14 |
OpenCV와 자바 - 3. 프로세싱-2 (0) | 2022.09.12 |
OpenCV와 자바 - 3. 프로세싱 (2) | 2022.09.11 |
OpenCV와 자바 - 2. 헬로 Camera (0) | 2022.09.09 |