-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dispose Webcam #121
Comments
Hi @rickguise, Thank you for the report. Can you please precise:
I suppose that after you dispose the dialog there is a thread remaining in background which is still fetching images from webcam (this would make FPS to drop by 1/2 at the first time, then by 1/3, then by 1/4 and so on), but it's really hard to say anything when I do not see the code - please try to run your app in debug and check threads list - you can then manually stop and start each one of them, which will make debugging easier. Webcam is being disposed only when you call it manually or the JVM is gracefully closed. After webcam is disposed it cannot be used (open) any more. Dispose means that it has been completely wiped out and all the allocated resources has been already freed. You can test if even works fine by disposing webcam manually (which is very bad option), or by writing something to file instead of stdout, when JVM is being closed, and webcam has been open prior to this fact. |
Hello sarxos! Thank you for the fast reply. I am using version webcam-capture-0.3.10-RC4. JDK 1.6.0_26 on Windows 7 64bit. I ran in debug mode and yes there are various pool threads running in the background. I did a very simple JFrame with one button that opens a JDialog: private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
TakeSnaphotFromVideoExample wv = new TakeSnaphotFromVideoExample();
wv.setVisible(true);
} I also added a close button to force the panel to stop. I want to be able to open and close the dialog many times, so what is the best way to do this? My JDialog code is as follows: package webcam;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamPanel;
import com.github.sarxos.webcam.WebcamResolution;
@SuppressWarnings("serial")
public class TakeSnaphotFromVideoExample extends JDialog {
private Executor executor = Executors.newSingleThreadExecutor();
private Dimension captureSize = WebcamResolution.VGA.getSize();
private Dimension displaySize = WebcamResolution.QQVGA.getSize();
private Webcam webcam = Webcam.getDefault();
private WebcamPanel panel = new WebcamPanel(webcam, displaySize, false);
private JButton btSnapMe = new JButton(new SnapMeAction());
private JButton btStart = new JButton(new StartAction());
private JButton btClose = new JButton(new CloseAction());
public TakeSnaphotFromVideoExample() {
setTitle("Java Webcam Capture POC");
webcam.setViewSize(captureSize);
panel.setFPSDisplayed(true);
panel.setFillArea(true);
btSnapMe.setEnabled(false);
setLayout(new FlowLayout());
add(panel);
add(btSnapMe);
add(btStart);
add(btClose);
pack();
setVisible(true);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
}
private class SnapMeAction extends AbstractAction {
public SnapMeAction() {
super("Snapshot");
}
@Override
public void actionPerformed(ActionEvent e) {
try {
File file = new File(String.format("test-%d.jpg", System.currentTimeMillis()));
ImageIO.write(webcam.getImage(), "JPG", file);
System.out.println("Image saved in " + file.getAbsolutePath());
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
private class StartAction extends AbstractAction implements Runnable {
public StartAction() {
super("Start");
}
@Override
public void actionPerformed(ActionEvent e) {
btStart.setEnabled(false);
btSnapMe.setEnabled(true);
executor.execute(this);
}
@Override
public void run() {
panel.start();
}
}
private class CloseAction extends AbstractAction {
public CloseAction() {
super("Close");
}
@Override
public void actionPerformed(ActionEvent e) {
webcam.close();
panel.stop();
dispose();
}
}
} Thanks! |
Thank you for the details. I will take a look on this later today :) |
I found the root cause and will fix this, however I will need to test few scenarios to check if I didn't break anything. The problem is caused by the listener which is not being dereferenced after panel is destroyed. As a temporary w/a you can add this line in the @Override
public void actionPerformed(ActionEvent e) {
webcam.close();
webcam.removeWebcamListener(panel); // ADD THIS LINE
panel.stop();
dispose();
} |
Hi sarxos, The removeWebcamListener fixed the issue. There is no frame loss now. Thanks and keep up the good work! |
Hi @rickguise, Thank you for your help and detailed problem description. The issue is now fixed. Would you like new release candidate to be deployed into repository? |
Hi sarxos, no it is not necessary. I am quite happy with the software. Thanks. |
Hi Example: |
Hello.
I transformed the WebcamViewerExample to a JDialog which is called from a JFrame and works fine until I close and reopen the dialog where the FPS falls to half. Each time I reopen the Dialog, the frames fall some more until the image is very slow. The System.out.println indicates multiple "webcam open" and "webcam closed", for example, the third time I open the JDialog, I get 3 "webcam open". I also tried putting webcam.close() and panel.stop() in the webcamClosed event.
Is this a Dispose problem, I cannot get the webcamDisposed event to fire.
Thanks
The text was updated successfully, but these errors were encountered: