1

I am having some problems with my program. I have a GUI that shows a live image from a webcam (using [jvacv][1]) in one side, and the captured image in the other. To capture the image, I have a button. One problem is that the captured image is refreshing only if I close and open the program again. The other is that I want to capture a 1080p image from webcam, but live image at 640x480.

Here is the code:

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException; 
import java.lang.ProcessBuilder.Redirect;


import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;

import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.FrameGrabber.Exception;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import static com.googlecode.javacv.cpp.opencv_highgui.*;


public class Final 
{
private VideoPanel videoPanel = new VideoPanel();
private ImagePanel imagePanel   = new ImagePanel();
private JButton jbtCapture = new JButton("Captura");
private JRadioButton jbtAutoCap = new JRadioButton("Captura Automatica");
private FrameGrabber vision;
private BufferedImage image;
private IplImage gimage;


public class VideoPanel extends JPanel
{

public VideoPanel()
{
    vision = new OpenCVFrameGrabber(0);
    try 
    {
        vision.start();
    } catch (Exception e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}


public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    try {
        image = vision.grab().getBufferedImage();
        if (image != null)
        {
            g.drawImage(image, 0, 0, 640, 480, null);
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    repaint();
}
}



class ImagePanel extends JPanel
{
private BufferedImage image;


public ImagePanel()
{
    try {
        image = ImageIO.read(new File("image001.bmp"));
    } catch (IOException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


public void paintComponent(Graphics g) 
{
    super.paintComponent(g);
    if(image != null)
    {

        g.drawImage(image,5,0,640,480, null);


    }

}


}



private void displayGUI()
{
JFrame janela = new JFrame();


JPanel jpButton = new JPanel();
jpButton.setLayout(null);


jbtCapture.setBounds(145,0,110,30);
jpButton.add(jbtCapture);

jbtAutoCap.setBounds(0, 5, 140, 23);
jpButton.add(jbtAutoCap);

janela.setLayout(null);

videoPanel.setBounds(5, 5, 640, 480);
janela.add(videoPanel);

imagePanel.setBounds(705,5,640,480);
janela.add(imagePanel);

jpButton.setBounds(5, 500, 670, 40);
janela.add(jpButton);

janela.setSize(1366,730);
janela.setVisible(true);


jbtCapture.addActionListener(
           new ActionListener() 
           {
              public void actionPerformed(ActionEvent e)
              {

                 try {
                    gimage = vision.grab();
                    cvSaveImage("image001.bmp", gimage);

                } catch (Exception e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }




              }
           }
       );

}



public static void main(String[] args) 
{
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() 
{

    @Override
    public void run() 
    {
        // TODO Auto-generated method stub
        new Final().displayGUI();
    }
});

}
}
rgPaiva
  • 39
  • 7
  • 1
    I suggest the culprit is **NOT using Event Dispatch Thread**. Please do read [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html) for detail. Moreover, why a `repaint()` request inside `paintComponent(...)` method, remove that, it's really not a good thingy to be done inside that method, calling that method indirectly from inside the same method. – nIcE cOw Sep 24 '12 at 15:31
  • If i remove repaint() , the image from the webcam doesn't refresh. I will read about Concurrency, ty, also have added some other issues that i am having. – rgPaiva Sep 24 '12 at 15:43
  • Never used the API myself, so can not provide much information in that area. Though what mistakes been committed by you in the Swing code is something I told you. Might be that refresh thingy will be sorted out once you put your code inside main method, within `SwingUtilities.invokeLater(new Runnable(){// Your Code here from main method.});` Upvoted the question for better attention :-) – nIcE cOw Sep 24 '12 at 15:50
  • Can you post a sample or modify the code? I am new at swing , and don't have enough time to read all the tutorial about Concurrency. Sorry for my english. – rgPaiva Sep 26 '12 at 14:58
  • To be true, if I had used this API of **javacv**, I would definitely have posted my comment as an answer, though I knew only about Swing, hence I can not give you more detail in that area. Just you have to put the code which is responsible for creating and displaying your GUI on the EDT, watch any [example](http://stackoverflow.com/a/11372350/1057230), which uses this approach. Just done't start Swing from your main, let `SwingUtilities.invokeLater(...)` do that for you on the EDT. If you are updating your GUI from any Thread created by your own self, always put that GUI updation code – nIcE cOw Sep 26 '12 at 15:09
  • inside `SwingUtilities.invokeLater(...)` thingy :-) – nIcE cOw Sep 26 '12 at 15:10
  • I edited the code, as you can see up there, need only to know if i need to put the actionPerformed in the DisplayGUI() or create a method, and look for a better way to show the image of the webcam in the jpanel , without repaint. Sorry for being stupid with swing , never had to use it before ;P – rgPaiva Sep 27 '12 at 11:03
  • Had you tried removing that repaint now paintComponent() method, is it working fine now. I guess the rest of the code is good (except for the Absolute Positioning instead of using a Proper Layout Manager). Events by default are on EDT, so nothing to worry on that. You simply can add ActionListeners to your `JButton` inside the displayGUI() method now, like button.addActionListener(new MyButtonListener()); that will do now. – nIcE cOw Sep 27 '12 at 11:53
  • Removing the repaint , doesn't work. But my real problem is the ImagePanel, not refreshing when i click the button. The button save a picture in project folder, then the ImagePanel class paint the image in the same ImagePanel, and this jpanel is inside the jframe. The program only refresh the image if i close and open again, i need a runtime refresh ;/ – rgPaiva Sep 27 '12 at 19:39
  • Here watch this [thread](http://stackoverflow.com/q/9849950/1057230), all examples doing runtime refresh, but not using repaint() inside the paintComponent() method. – nIcE cOw Sep 28 '12 at 02:42
  • BTW, you can check how I'm doing it in `CanvasFrame` and do something similar in your own `Frame`. That should work better. – Samuel Audet Jan 05 '13 at 05:10

0 Answers0