Gestion de la webcam avec JMF ... Image noire...

Gestion de la webcam avec JMF ... Image noire... - Java - Programmation

Marsh Posté le 03-07-2004 à 18:30:24    

Salut,
grace à l'exemple fourni par Sun, j'arrive à récupérer une image de ma webcam (objet Image).
Seulement voila, l'image récupérée est mise dans un JLabel pour la voir rapidement (pour tester simplement), et il se trouve qu'elle est noire (j'avais testé aussi de faire un fichier avec ImageIO et idem).
Ma caméra est bien détectée de plus je vois sa diode clignoter lorsque que le programme s'initialise.
De plus aucune exception n'est lancée, tout se déroule bien je pense.
 
http://java.sun.com/dev/evangcentr [...] h/jmf.html
c'est le code que j'ai repris, le code intégral est dans le zip en bas de page...
 
ah oui et aussi quand on a fini avec la webcam, je fais :
deviceProc.close();
formattedSource.disconnect();
ça va ? y a un des 2 qui est inutile ?
merci
   ANT


Message édité par antsite le 03-07-2004 à 19:24:54
Reply

Marsh Posté le 03-07-2004 à 18:30:24   

Reply

Marsh Posté le 03-07-2004 à 19:22:01    

le code :

Code :
  1. public class CamWorker implements ControllerListener
  2. {
  3. private Object stateLock = new Object();
  4. private DataSource formattedSource; //lien avec le hardware
  5. private Processor deviceProc; //Processor and not a player to access data
  6. private PushBufferStream camStream;
  7. private BufferToImage converter;
  8. public CamWorker() throws CamException
  9. {
  10.  final String camName = "vfw:Microsoft WDM Image Capture (Win32):0"; //c ok j'ai testé avant en listant tout
  11.  CaptureDeviceInfo device = CaptureDeviceManager.getDevice(camName);
  12.  if(device == null)
  13.   throw new CamException("Device not found" );
  14.  //get RGB format
  15.  RGBFormat userFormat = null;
  16.  Format[] cfmt = device.getFormats();
  17.  userFormat = (RGBFormat)cfmt[1]; //160x120
  18.  //get url to the device
  19.  MediaLocator loc = device.getLocator();
  20.  if(loc == null)
  21.   throw new CamException("Unable to get MediaLocator for device" );
  22.  //lien avec le hardware
  23.  try
  24.  {
  25.   formattedSource = Manager.createDataSource(loc);
  26.  }
  27.  catch(Exception ex)
  28.  {
  29.   throw new CamException("Unable to get DataSource" );
  30.  }
  31.  //recup les formats possible de la cam
  32.  FormatControl[] fmtControls = ((CaptureDevice)formattedSource).getFormatControls();
  33.  if(fmtControls == null || fmtControls.length == 0)
  34.   throw new CamException("No available format" );
  35.  //voir si on a notre format disponible (RGB)
  36.  Format setFormat = null;
  37.  for(int i=0; i<fmtControls.length; i++)
  38.  {
  39.   if(fmtControls[i] == null)
  40.    continue;
  41.   if((setFormat=fmtControls[i].setFormat(userFormat)) != null)
  42.    break;
  43.  }
  44.  if(setFormat == null)
  45.   throw new CamException("Choosen format not available" );
  46.  //connect to the dataSource
  47.  try
  48.  {
  49.   formattedSource.connect();
  50.  }
  51.  catch(Exception ioe)
  52.  {
  53.   throw new CamException("Unable to connect the DataSource" );
  54.  }
  55.  //Using of a processor instead of a player to access the data
  56.  try
  57.  {
  58.   deviceProc = Manager.createProcessor(formattedSource);
  59.  }
  60.  catch(Exception ex)
  61.  {
  62.   throw new CamException("Unable to get Processor for device" );
  63.  }
  64.  //put Processor in Realized state (non-blocking method), so
  65.  //Listener needed to see when realized state effective
  66.  deviceProc.addControllerListener(this);
  67.     deviceProc.realize();
  68.    
  69.     //wait to be in realized state
  70.     while(deviceProc.getState() != Controller.Realized)
  71.     {
  72.      synchronized(stateLock)
  73.   {
  74.       try
  75.    {
  76.        stateLock.wait();
  77.       }
  78.       catch(InterruptedException ie)
  79.    {
  80.        throw new CamException("Interruption" );
  81.       }
  82.      }
  83.     }
  84.    
  85.     //now we can start
  86.     deviceProc.start();
  87.    
  88.     //Source buffer
  89.     PushBufferDataSource source = null;
  90.  try
  91.  {
  92.   source = (PushBufferDataSource)deviceProc.getDataOutput();
  93.  }
  94.  catch(NotRealizedError nre)
  95.  {
  96.   throw new CamException("Cannot getData from device" );
  97.  }
  98.  //get streams from source buffer
  99.  PushBufferStream[] streams = source.getStreams();
  100.  camStream = null;
  101.  for(int i=0; i<streams.length; i++)
  102.  {
  103.   //Use the first Stream that is RGBFormat (there should be only one)
  104.   if(streams[i].getFormat() instanceof RGBFormat)
  105.   {
  106.    camStream = streams[i];
  107.    RGBFormat rgbf = (RGBFormat)streams[i].getFormat();
  108.    converter = new BufferToImage(rgbf);
  109.    break;
  110.   }
  111.  }
  112.     //*** ready to capture ***
  113. }
  114. //Do not forget to call this
  115. public void closeCam()
  116. {
  117.  deviceProc.close();
  118.         formattedSource.disconnect();
  119. }
  120.  
  121. public Image getImage() throws CamException
  122. {
  123.  Buffer b = new Buffer();
  124.  try
  125.  {
  126.   camStream.read(b);
  127.  }
  128.  catch(Exception ioe)
  129.  {
  130.   throw new CamException("Unable to capture frame from camera" );
  131.  }
  132.  
  133.  Image img = converter.createImage(b);
  134.  return img;
  135. }
  136.  
  137. public void controllerUpdate(ControllerEvent e)
  138. {
  139.  if(e instanceof RealizeCompleteEvent)
  140.  {
  141.   //Realize transition completed
  142.   synchronized(stateLock)
  143.   {
  144.    stateLock.notifyAll();
  145.   }
  146.  }
  147. }
  148. }

Reply

Marsh Posté le 05-07-2004 à 16:22:25    

antsite a écrit :


Seulement voila, l'image récupérée est mise dans un JLabel pour la voir rapidement (pour tester simplement), et il se trouve qu'elle est noire (j'avais testé aussi de faire un fichier avec ImageIO et idem).


 
Si le problème avec un fichier, t'embête pas avec le code pour JMF.
Essaie déjà de résoudre ton pb d'affichage d'une simple image ...
Sinon, tu risques d'introduire d'autres erreurs, et de pas pouvoir te concentrer sur le bug à trouver.
 
Bon courage

Reply

Marsh Posté le 05-07-2004 à 16:24:50    

Je comprends pas bien ce que tu veux me dire... !
Mon problème est simple je pense : le code ci-dessus me permet de récupérer un objet Image contenant une image prise avec la webcam et il se trouve que cette image est noire, donc j'en déduit que la capture c'est mal passée ?
y a un truc qui m'échappe ?

Reply

Marsh Posté le 05-07-2004 à 16:26:32    

ok, mais tu as dit :

antsite a écrit :


Seulement voila, l'image récupérée est mise dans un JLabel pour la voir rapidement (pour tester simplement), et il se trouve qu'elle est noire (j'avais testé aussi de faire un fichier avec ImageIO et idem).


 
donc, à moins que je n'ai pas compris, tu as le même problème avec une image chargée depuis le disque.
non ?

Reply

Marsh Posté le 05-07-2004 à 16:27:00    

ha non ok, ça y est j'ai compris :D

Reply

Marsh Posté le 05-07-2004 à 16:28:05    

pour la suite désolé, mais j'ai pas d'idée !

Reply

Marsh Posté le 05-07-2004 à 16:28:47    

non non ce que je voulais dire c'est qu'au début j'ai pensais que je faisais peut être une erreur lors de la création d'un fichier jpg avec ladite image. Quand je visualisais ce fichier, l'image était noire.
Bon donc je me suis dit pour être sur que le problème vient pas de la je m'embête plus avec ça je mets directement l'image dans un JLabel et je la visualise normalement avec une JFrame. voila ! Et donc dans la JFrame j'ai un gros rectangle noir...

Reply

Marsh Posté le 06-07-2004 à 00:28:33    

ca me fait penser, qd on fait un screeshot sur une video elle apparait souvent toute noire , quelque chose me dit que t'as un truc du genre.
 
j'arrive


Message édité par veryfree le 06-07-2004 à 00:35:49
Reply

Marsh Posté le 06-07-2004 à 00:32:44    

bon en fait j'arrive plus a remettre la main sur un exemple que j'avait sur mon pc dsl mais google regorge d'exemples
 
 
 
 
edit: voila qui devrait t'interesser ;)
 
http://forum.java.sun.com/thread.j [...] ge=1816659
 

Code :
  1. import javax.swing.*;
  2. import javax.swing.event.*;
  3. import java.io.*;
  4. import javax.media.*;
  5. import javax.media.format.*;
  6. import javax.media.util.*;
  7. import javax.media.control.*;
  8. import javax.media.protocol.*;
  9. import java.util.*;
  10. import java.awt.*;
  11. import java.awt.image.*;
  12. import java.awt.event.*;
  13. import com.sun.image.codec.jpeg.*;
  14. public class SwingCapture extends Panel implements ActionListener
  15. {
  16.   public static Player player = null;
  17.   public CaptureDeviceInfo di = null;
  18.   public MediaLocator ml = null;
  19.   public JButton capture = null;
  20.   public Buffer buf = null;
  21.   public Image img = null;
  22.   public VideoFormat vf = null;
  23.   public BufferToImage btoi = null;
  24.   public ImagePanel imgpanel = null;
  25.  
  26.   public SwingCapture()
  27.   {
  28.     setLayout(new BorderLayout());
  29.     setSize(320,550);
  30.    
  31.     imgpanel = new ImagePanel();
  32.     capture = new JButton("Capture" );
  33.     capture.addActionListener(this);
  34.    
  35.     String str1 = "vfw:Logitech USB Video Camera:0";
  36.     String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";
  37.     di = CaptureDeviceManager.getDevice(str2);
  38.     ml = di.getLocator();
  39.    
  40.     try
  41.     {
  42.       player = Manager.createRealizedPlayer(ml);
  43.       player.start();
  44.       Component comp;
  45.      
  46.       if ((comp = player.getVisualComponent()) != null)
  47.       {
  48.         add(comp,BorderLayout.NORTH);
  49.       }
  50.       add(capture,BorderLayout.CENTER);
  51.       add(imgpanel,BorderLayout.SOUTH);
  52.     }
  53.     catch (Exception e)
  54.     {
  55.       e.printStackTrace();
  56.     }
  57.   }
  58.  
  59.   public static void main(String[] args)
  60.   {
  61.     Frame f = new Frame("SwingCapture" );
  62.     SwingCapture cf = new SwingCapture();
  63.    
  64.     f.addWindowListener(new WindowAdapter() {
  65.       public void windowClosing(WindowEvent e) {
  66.       playerclose();
  67.       System.exit(0);}});
  68.    
  69.     f.add("Center",cf);
  70.     f.pack();
  71.     f.setSize(new Dimension(320,550));
  72.     f.setVisible(true);
  73.   }
  74.  
  75.  
  76.   public static void playerclose()
  77.   {
  78.     player.close();
  79.     player.deallocate();
  80.   }
  81.  
  82.   public void actionPerformed(ActionEvent e)
  83.   {
  84.     JComponent c = (JComponent) e.getSource();
  85.    
  86.     if (c == capture)
  87.     {
  88.       // Grab a frame
  89.       FrameGrabbingControl fgc = (FrameGrabbingControl)
  90.       player.getControl("javax.media.control.FrameGrabbingControl" );
  91.       buf = fgc.grabFrame();
  92.      
  93.       // Convert it to an image
  94.       btoi = new BufferToImage((VideoFormat)buf.getFormat());
  95.       img = btoi.createImage(buf);
  96.      
  97.       // show the image
  98.       imgpanel.setImage(img);
  99.      
  100.       // save image
  101.       saveJPG(img,"c:\\test.jpg" );
  102.     }
  103.   }
  104.  
  105.   class ImagePanel extends Panel
  106.   {
  107.     public Image myimg = null;
  108.    
  109.     public ImagePanel()
  110.     {
  111.       setLayout(null);
  112.       setSize(320,240);
  113.     }
  114.    
  115.     public void setImage(Image img)
  116.     {
  117.       this.myimg = img;
  118.       repaint();
  119.     }
  120.    
  121.     public void paint(Graphics g)
  122.     {
  123.       if (myimg != null)
  124.       {
  125.         g.drawImage(myimg, 0, 0, this);
  126.       }
  127.     }
  128.   }
  129.  
  130.   public static void saveJPG(Image img, String s)
  131.   {
  132.     BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
  133.     Graphics2D g2 = bi.createGraphics();
  134.     g2.drawImage(img, null, null);
  135.     FileOutputStream out = null;
  136.     try
  137.     {
  138.       out = new FileOutputStream(s);
  139.     }
  140.     catch (java.io.FileNotFoundException io)
  141.     {
  142.       System.out.println("File Not Found" );
  143.     }
  144.    
  145.     JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
  146.     JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
  147.     param.setQuality(0.5f,false);
  148.     encoder.setJPEGEncodeParam(param);
  149.    
  150.     try
  151.     {
  152.       encoder.encode(bi);
  153.       out.close();
  154.     }
  155.     catch (java.io.IOException io)
  156.     {
  157.       System.out.println("IOException" );
  158.     }
  159.   }
  160.  
  161. }


 
A+


Message édité par veryfree le 06-07-2004 à 00:37:24
Reply

Marsh Posté le 06-07-2004 à 00:32:44   

Reply

Marsh Posté le 06-07-2004 à 00:39:16    

sinon y a un jocebug avec les balises c/c++ : deux mots clés d'affilé et il vire l'espace [:mmmfff]


Message édité par veryfree le 06-07-2004 à 00:39:28
Reply

Marsh Posté le 06-07-2004 à 08:03:00    

merci! je teste ça ce soir :hello:

Reply

Marsh Posté le 06-07-2004 à 13:43:43    

j'ai testé et ca marche niquel :)

Reply

Marsh Posté le 06-07-2004 à 20:28:43    

Oui l'exemple marche bien effet. Maintenant j'ai encore un problème :
je fais comme avant
 

Code :
  1. CamWorker camWork = new CamWorker();
  2. Image img = camWork.getImage();


 
seulement voila img est null car la cam n'a pas le temps de s'initialiser ! Donc j'ai repris comme dans mon premier post pour attendre le RealizedState, et bien même avec ça (et aussi StartEvent j'ai essayé) il n'attends pas tout à fait que la caméra soit prête.
Si par contre je mets un Thread.sleep(2000); avec le getImage c'est bon ça marche.
Quelqu'un voit comment savoir que la cam est prête ?

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed