Já procurei em vários tópicos mas não estou conseguindo achar uma resposta.
Meu atual formulário GUI mostra a imagem da webcam e é possível tirar fotos e salva-las no computador. Porém eu queria que quando o usuário apertasse ‘Gravar’ começasse a gravar e o botoão mudasse para ‘Parar’. Quando ele clicar de novo a gravação para e salva o arquivo.
As outras coisas eu sei fazer, como os Botões e o JFileChooser, mas eu só queria saber COMO GRAVAR?
OBS: Para tirar fotos uso o JFM.
Abraços, Gustavo Borba.
E em JFM, não haveria um jeito?
Boa noite a todos.
Depois de voce intalar o Java Media Framework (JMF), baixe-o no link abaixo, voce então pode usar o código logo a seguir:
http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/download.html.
import java.awt.Image;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.media.Buffer;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.VideoFormat;
import javax.media.util.BufferToImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;
public class WebCamCapture extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private Player player;
private CaptureDeviceInfo di;
private MediaLocator ml;
private JPanel painelbotoes;
private JButton start = null;
private JButton capture = null;
public JButton clearimage = null;
public JButton confirm = null;
public Buffer buf = null;
public Image img = null;
// public VideoFormat vf = null;
public BufferToImage btoi = null;
public Component webcam = null;
public static void main(String args[]){
JFrame wcam = new WebCamCapture();
wcam.setTitle("Captura de Imagem");
}
public WebCamCapture(){
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
painelbotoes = new JPanel();
painelbotoes.setLayout(new GridLayout(1,4));
start = new JButton("Iniciar");
start.addActionListener(this);
capture = new JButton("Capture");
capture.addActionListener(this);
capture.setEnabled(false);
clearimage = new JButton("Limpar");
clearimage.addActionListener(this);
clearimage.setEnabled(false);
confirm = new JButton("Gravar");
confirm.addActionListener(this);
confirm.setEnabled(false);
painelbotoes.add(start);
painelbotoes.add(capture);
painelbotoes.add(clearimage);
painelbotoes.add(confirm);
add(painelbotoes, BorderLayout.NORTH);
di = CaptureDeviceManager.getDevice("vfw//0");
ml = new MediaLocator("vfw://0");
pack();
this.setSize(400,400);
this.setLocationRelativeTo(this);
this.setVisible(true);
}
public void playerClose(){
player.close();
player.deallocate();
player = null;
}
public void actionPerformed(ActionEvent e){
if (e.getSource()==start){
try {
player = Manager.createRealizedPlayer(ml);
webcam = player.getVisualComponent();
if (webcam!=null) add(webcam, BorderLayout.CENTER);
player.start();
validate();
} catch(Exception ex){
JOptionPane.showMessageDialog(null,"Não foi possível conectar ao dispositivo de captura\n"+ex.getMessage());
ex.printStackTrace();
}
start.setEnabled(false);
capture.setEnabled(true);
} else if (e.getSource()==capture){
FrameGrabbingControl fgc=(FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl");
buf = fgc.grabFrame();
btoi = new BufferToImage((VideoFormat)buf.getFormat());
img = btoi.createImage(buf);
playerClose();
capture.setEnabled(false);
clearimage.setEnabled(true);
confirm.setEnabled(true);
} else if (e.getSource()==clearimage){
remove(webcam);
webcam = null;
clearimage.setEnabled(false);
confirm.setEnabled(false);
start.setEnabled(true);
} else if (e.getSource()==confirm){
gravaImg(img);
System.exit(0);
}
}
public void gravaImg(Image imagem){
File arquivo = new File("C:/Temp/Teste.jpg");
try {
if (!arquivo.exists()){
FileOutputStream fo = new FileOutputStream(arquivo);
}
ImageIO.write((RenderedImage)imagem, "JPG", arquivo);
} catch(IOException ex){
JOptionPane.showMessageDialog(null, "Não foi possível encontrar o caminho especificado");
ex.printStackTrace();
}
}
}
Execute e vê se é o que voce queria.
A jmf usa o vídeo for windows(vfw), que está para ser excluído das próximas versões do windows(7 em diante). A dsj usa directshow e pinta o vídeo em cima do direct3d, com a vmr9. Além da dsj ser bem mais simples de se usar.
A aplicação abaixo realiza uma simples captura para um arquivo de vídeo.
[code]/**
dsj demo code.
You may use, modify and redistribute this code under the terms laid out in the header of the DSJDemo application.
copyright 2005-7
N.Peters
humatic GmbH
Berlin, Germany
**/
import de.humatic.dsj.*;
public class SimpleCapture implements java.beans.PropertyChangeListener {
private DSCapture graph;
public SimpleCapture() {}
public void createGraph() {
javax.swing.JFrame f = new javax.swing.JFrame("dsj SimpleCapture");
DSFilterInfo[][] dsi = DSCapture.queryDevices();
graph = new DSCapture(DSFiltergraph.RENDER_NATIVE, dsi[0][2], false, DSFilterInfo.doNotRender(), this);
f.add(java.awt.BorderLayout.CENTER, graph.asComponent());
f.add(java.awt.BorderLayout.SOUTH, new SwingMovieController(graph));
final javax.swing.JButton toFile = new javax.swing.JButton("set capture file");
toFile.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
if (graph.getState() == DSCapture.PREVIEW) {
graph.setCaptureFile("captureTest.asf", DSFilterInfo.doNotRender(), DSFilterInfo.doNotRender(), true);
toFile.setText("set preview");
graph.record();
} else {
graph.setPreview();
toFile.setText("set capture file");
}
}
});
f.add(java.awt.BorderLayout.NORTH, toFile);
f.pack();
f.setVisible(true);
javax.swing.JFrame jf = new javax.swing.JFrame("Device control");
jf.setLayout(new java.awt.GridLayout(0,1));
if (((DSCapture)graph).getActiveVideoDevice() != null && ((DSCapture)graph).getActiveVideoDevice().getControls() != null) {
for (int i = CaptureDeviceControls.BRIGHTNESS; i < CaptureDeviceControls.FOCUS; i++) try { jf.add(((DSCapture)graph).getActiveVideoDevice().getControls().getController(i, 0, true)); }catch (Exception ex){}
}
if (((DSCapture)graph).getActiveAudioDevice() != null) for (int i = CaptureDeviceControls.MASTER_VOL; i < CaptureDeviceControls.TREBLE; i++) try { jf.add(((DSCapture)graph).getActiveAudioDevice().getControls().getController(i, 0, true)); }catch (Exception ex){}
if (jf.getContentPane().getComponentCount() == 0) return;
jf.pack();
jf.setVisible(true);
/**
Don't do this at home. This demo relies on dsj closing and disposing off filtergraphs when the JVM exits. This is
OK for a "open graph, do something & exit" style demo, but real world applications should take care of calling
dispose() on filtergraphs they're done with themselves.
**/
f.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
}
public void propertyChange(java.beans.PropertyChangeEvent pe) {
System.out.println("received event or callback from "+pe.getPropagationId());
}
public static void main(String[] args){
new SimpleCapture().createGraph();
}
}[/code]
Olá, discorpio.
Esse código eu já tenho. Eu gostaria é de gravar um VÍDEO.
Abraços, Gustavo Borba.
[quote=GustavoBorba]Olá, discorpio.
Esse código eu já tenho. Eu gostaria é de gravar um VÍDEO.
Abraços, Gustavo Borba.[/quote]
[code]/**
dsj demo code.
You may use, modify and redistribute this code under the terms laid out in the header of the DSJDemo application.
copyright 2005-7
N.Peters
humatic GmbH
Berlin, Germany
**/
import de.humatic.dsj.*;
public class SimpleCapture implements java.beans.PropertyChangeListener {
private DSCapture graph;
public SimpleCapture() {}
public void createGraph() {
javax.swing.JFrame f = new javax.swing.JFrame("dsj SimpleCapture");
DSFilterInfo[][] dsi = DSCapture.queryDevices();
graph = new DSCapture(DSFiltergraph.RENDER_NATIVE, dsi[0][2], false, DSFilterInfo.doNotRender(), this);
f.add(java.awt.BorderLayout.CENTER, graph.asComponent());
f.add(java.awt.BorderLayout.SOUTH, new SwingMovieController(graph));
final javax.swing.JButton toFile = new javax.swing.JButton("set capture file");
toFile.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
if (graph.getState() == DSCapture.PREVIEW) {
graph.setCaptureFile("captureTest.asf", DSFilterInfo.doNotRender(), DSFilterInfo.doNotRender(), true);
toFile.setText("set preview");
graph.record();
} else {
graph.setPreview();
toFile.setText("set capture file");
}
}
});
f.add(java.awt.BorderLayout.NORTH, toFile);
f.pack();
f.setVisible(true);
javax.swing.JFrame jf = new javax.swing.JFrame("Device control");
jf.setLayout(new java.awt.GridLayout(0,1));
if (((DSCapture)graph).getActiveVideoDevice() != null && ((DSCapture)graph).getActiveVideoDevice().getControls() != null) {
for (int i = CaptureDeviceControls.BRIGHTNESS; i < CaptureDeviceControls.FOCUS; i++) try { jf.add(((DSCapture)graph).getActiveVideoDevice().getControls().getController(i, 0, true)); }catch (Exception ex){}
}
if (((DSCapture)graph).getActiveAudioDevice() != null) for (int i = CaptureDeviceControls.MASTER_VOL; i < CaptureDeviceControls.TREBLE; i++) try { jf.add(((DSCapture)graph).getActiveAudioDevice().getControls().getController(i, 0, true)); }catch (Exception ex){}
if (jf.getContentPane().getComponentCount() == 0) return;
jf.pack();
jf.setVisible(true);
/**
Don't do this at home. This demo relies on dsj closing and disposing off filtergraphs when the JVM exits. This is
OK for a "open graph, do something & exit" style demo, but real world applications should take care of calling
dispose() on filtergraphs they're done with themselves.
**/
f.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
}
public void propertyChange(java.beans.PropertyChangeEvent pe) {
System.out.println("received event or callback from "+pe.getPropagationId());
}
public static void main(String[] args){
new SimpleCapture().createGraph();
}
}[/code]
Ocorre esse erro:
[quote]Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 2
at app.createGraph(app.java:15)
at app.main(app.java:89)
Java Result: 1
[/quote]
[quote=GustavoBorba]Ocorre esse erro:
[quote]Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 2
at app.createGraph(app.java:15)
at app.main(app.java:89)
Java Result: 1
[/quote][/quote]
Porque sua máquina deve ter apenas 1 dispositivo de captura.
graph = new DSCapture(DSFiltergraph.RENDER_NATIVE, dsi[0][2], false, DSFilterInfo.doNotRender(), this);
pode usar assim
graph = new DSCapture(DSFiltergraph.RENDER_NATIVE, dsi[0][0], false, DSFilterInfo.doNotRender(), this);
Se você receber o erro novamente, coloque um breakepoint na linha, e veja em qual índice do vetor dsi está o dispositivo de vídeo.
[color=darkblue]Tem o Source no final :[/color]
Record Movies with Java Media Framework (JMF)