Webcam ansteuern

ankmanu

Bekanntes Mitglied
Hi@all,

ich bin gerade mal wieder am verzweifeln:
auf meinem alten Rechner lief folgender Code perfekt, um eine Webcam per Java anzusteuern und per Button ein Bild aufzunehmen und zu speichern:
Java:
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import javax.media.*;
import javax.media.format.*;
import javax.media.util.*;
import javax.media.control.*;
import javax.media.protocol.*;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import com.sun.image.codec.jpeg.*;
 
public class SwingCapture extends Panel implements ActionListener 
{
  public static Player player = null;
  public CaptureDeviceInfo di = null;
  public MediaLocator ml = null;
  public JButton capture = null;
  public Buffer buf = null;
  public Image img = null;
  public VideoFormat vf = null;
  public BufferToImage btoi = null;
  public ImagePanel imgpanel = null;
  
  public SwingCapture() 
  {
    setLayout(new BorderLayout());
    setSize(320,550);
    
    imgpanel = new ImagePanel();
    capture = new JButton("Capture");
    capture.addActionListener(this);
    
    String str1 = "vfw:Logitech USB Video Camera:0";
    String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";
    di = CaptureDeviceManager.getDevice(str2);
    ml = di.getLocator();
    
    try 
    {
      player = Manager.createRealizedPlayer(ml);
      player.start();
      Component comp;
      
      if ((comp = player.getVisualComponent()) != null)
      {
        add(comp,BorderLayout.NORTH);
      }
      add(capture,BorderLayout.CENTER);
      add(imgpanel,BorderLayout.SOUTH);
    } 
    catch (Exception e) 
    {
      e.printStackTrace();
    }
  }
 
 
  
  public static void main(String[] args) 
  {
    Frame f = new Frame("SwingCapture");
    SwingCapture cf = new SwingCapture();
    
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
      playerclose();
      System.exit(0);}});
    
    f.add("Center",cf);
    f.pack();
    f.setSize(new Dimension(320,550));
    f.setVisible(true);
  }
  
  
  public static void playerclose() 
  {
    player.close();
    player.deallocate();
  }
  
 
  public void actionPerformed(ActionEvent e) 
  {
    JComponent c = (JComponent) e.getSource();
    
    if (c == capture) 
    {
      // Grab a frame
      FrameGrabbingControl fgc = (FrameGrabbingControl)
      player.getControl("javax.media.control.FrameGrabbingControl");
      buf = fgc.grabFrame();
      
      // Convert it to an image
      btoi = new BufferToImage((VideoFormat)buf.getFormat());
      img = btoi.createImage(buf);
      
      // show the image
      imgpanel.setImage(img);
      
      // save image
      saveJPG(img,"c:\\test.jpg");
    }
  }
  
  class ImagePanel extends Panel 
  {
    public Image myimg = null;
    
    public ImagePanel() 
    {
      setLayout(null);
      setSize(320,240);
    }
    
    public void setImage(Image img) 
    {
      this.myimg = img;
      repaint();
    }
    
    public void paint(Graphics g) 
    {
      if (myimg != null) 
      {
        g.drawImage(myimg, 0, 0, this);
      }
    }
  }
  
 
  public static void saveJPG(Image img, String s)
  {
    BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = bi.createGraphics();
    g2.drawImage(img, null, null);
 
    FileOutputStream out = null;
    try
    { 
      out = new FileOutputStream(s); 
    }
    catch (java.io.FileNotFoundException io)
    { 
      System.out.println("File Not Found"); 
    }
    
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
    param.setQuality(0.5f,false);
    encoder.setJPEGEncodeParam(param);
    
    try 
    { 
      encoder.encode(bi); 
      out.close(); 
    }
    catch (java.io.IOException io) 
    {
      System.out.println("IOException"); 
    }
  }
  
}
Doch nun habe ich einen neuen PC mit Betriebssystem Windows 7. Der Code läuft nicht mehr! Ich musste mir eine neue Webcam kaufen, weil die alte nicht Win7 fähig war.
Der Code stammt aus folgendem Thread:
Java Media Framework - Here is the source code to JMF Webcam app + saves jpeg [Locked]
Ich habe die dort genannten Lösungen ausprobiert, um das Problem zu lösen.

Java:
ml = di.getLocator();
durch
Java:
ml = new MediaLocator("vfw://0");
ersetzt.
Bei der Lösung treten (wie in dem Thread beschrieben) die folgenden Probleme/Exceptions auf:
Java:
java.lang.RuntimeException: No permission to capture from applets
java.lang.RuntimeException: No permission to capture from applets
javax.media.NoPlayerException: Error instantiating class: com.sun.media.protocol.vfw.DataSource : java.lang.RuntimeException: No permission to capture from applets
	at javax.media.Manager.createPlayerForContent(Manager.java:1362)
	at javax.media.Manager.createPlayer(Manager.java:417)
	at javax.media.Manager.createRealizedPlayer(Manager.java:553)
	at SwingCapture.<init>(SwingCapture.java:45)
	at SwingCapture.main(SwingCapture.java:67)
	at __SHELL1.run(__SHELL1.java:7)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at bluej.runtime.ExecServer$3.run(ExecServer.java:814)
Um die Probleme(for allem das: no permission to capture from applets)zu beheben, habe folgendes hinzugefügt:
Java:
import com.sun.media.util.JMFI18N;
import com.sun.media.util.Registry;
import java.io.*;
class AllowCapture
{
  public static void main(String args[])
  {
    Registry.set("secure.allowCaptureFromApplets", new Boolean(true));
    try 
    {
      Registry.commit();
      
    }
    catch (IOException ioe) 
    {
      System.out.println("error");
    }
  }
}
Das Programm kann übersetzt werden, allerdings tritt beim ausführen folgender Securityfehler auf:
Java:
java.lang.SecurityException: commit: Permission denied
	at com.sun.media.util.Registry.commit(Registry.java:251)
	at AllowCapture.main(AllowCapture.java:12)
Was kann ich tun, um das Programm zum laufen zu kriegen??
Aus dem weiteren Threadverlauf kann ich auch nichts nützliches/funktionierendes entnehmen 🙁

Die Webcam ist übrigens die Linq 16.0 Mega Pixel Webcam RW-16 (falls das irgendwas bringt), im Geräte-Manager wird Sie "Vimicro USB2.0 UVC PC Camera" genannt. Die Webcam funktioniert mit den mitgelieferten Programmen einwandfrei, also kann es (eigentlich) nicht an Ihr liegen 🙂

Viele Grüße
manu
 
Benutzt du denn ein Applet? Sicher für die Anzeige deines Webcam-Streams im Internet, oder?
In den FAQs findest du einen Beitrag, wie man Applets signiert und in HTML-Seiten einbindet.

Falls es das nicht war, musst du noch mal nachhaken.
 
Nein, ich will das ganze nicht einbinden, es soll einfach ein Programm werden, was ein Bild aufnimmt und speichert. Es muss eben auch kein Applet sein (wäre sogar besser wenn nicht) sondern es muss nur funktionieren! 🙂

Viele Grüße
manu
 
Aha, und wozu sind dann die Zeilen 8-17 in AllowCapture.java drin?
Halte dich erstmal an den Beispielcode, bevor du anfängst, ihn zu modifizieren.

Und noch was: Vermeide unbedingt die Mischung von AWT- und Swing-GUI-Komponenten, das könnte mal Probleme bei der Anzeige geben. Das wurde im Beispielcode im Link verkehrt gemacht.
 
Hi,

naja das mit den Zeilen 8-17 war nur als Versuch. Im Thread steht, das man den Code in ein Applet "überstetzen" kann, das würde ich auch gerne machen.

Aber wie kann man das machen??
Ich hab mal angefangen, glaube aber nicht das das stimmt:
Java:
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import javax.media.*;
import javax.media.format.*;
import javax.media.util.*;
import javax.media.control.*;
import javax.media.protocol.*;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import com.sun.image.codec.jpeg.*;
 
public class SwingCaptureer extends JApplet implements ActionListener 
{
  public static Player player = null;
  public CaptureDeviceInfo di = null;
  public MediaLocator ml = null;
  public JButton capture = null;
  public Buffer buf = null;
  public Image img = null;
  public VideoFormat vf = null;
  public BufferToImage btoi = null;
  public ImagePanel imgpanel = null;
  
  public void init() {
      SwingCapture swingc = new SwingCapture();
    }
  class SwingCapture extends Panel
  {
...
Ab dem "..." geht der Code allerdings nicht mehr!
Wie muss man das ganze denn aufbauen, wenn man
1)
Java:
... extends JApplet
drin haben will/muss und
2)
Java:
... extends Panel
auch drin haben muss???

Viele Grüße und dank schon mal
manu
 
Lass den SwingCaptureer von JPanel erben. Alle AWT-Klassen sollten auf Swing umgesetzt werden.
So weit ich das sehe, genügt ein 'J' vor dem Name der AWT-Komponente.

Das JPanel setzt du dann einfach ins JApplet.
bspw.
Java:
public void init() {
   setLayout(new BorderLayout());
   add(new SwingCaptureer());

   [...]
}
 
Zuletzt bearbeitet:
Danke,

das Programm sieht jetzt wie folgt aus und kann ausgeführt werden:
Java:
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import javax.media.*;
import javax.media.format.*;
import javax.media.util.*;
import javax.media.control.*;
import javax.media.protocol.*;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import com.sun.image.codec.jpeg.*;
 
public class SwingCaptureer extends JApplet implements ActionListener 
{
  public static Player player = null;
  public CaptureDeviceInfo di = null;
  public MediaLocator ml = null;
  public JButton capture = null;
  public Buffer buf = null;
  public Image img = null;
  public VideoFormat vf = null;
  public BufferToImage btoi = null;
  public ImagePanel imgpanel = null;
  
  public void ini() {
   setLayout(new BorderLayout());
   add(new SwingCaptureer());
 
    setLayout(new BorderLayout());
    setSize(320,550);
    
    imgpanel = new ImagePanel();
    capture = new JButton("Capture");
    capture.addActionListener(this);
    
    String str1 = "vfw:Logitech USB Video Camera:0";
    String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";
    di = CaptureDeviceManager.getDevice(str2);
    ml = di.getLocator();
    
    try 
    {
      player = Manager.createRealizedPlayer(ml);
      player.start();
      Component comp;
      
      if ((comp = player.getVisualComponent()) != null)
      {
        add(comp,BorderLayout.NORTH);
      }
      add(capture,BorderLayout.CENTER);
      add(imgpanel,BorderLayout.SOUTH);
    } 
    catch (Exception e) 
    {
      e.printStackTrace();
    }
  }
 
 
  
  public static void main(String[] args) 
  {
    Frame f = new Frame("SwingCapture");
    SwingCaptureer cf = new SwingCaptureer();
    
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
      playerclose();
      System.exit(0);}});
    
    f.add("Center",cf);
    f.pack();
    f.setSize(new Dimension(320,550));
    f.setVisible(true);
  }
  
  
  public static void playerclose() 
  {
    player.close();
    player.deallocate();
  }
  
 
  public void actionPerformed(ActionEvent e) 
  {
    JComponent c = (JComponent) e.getSource();
    
    if (c == capture) 
    {
      // Grab a frame
      FrameGrabbingControl fgc = (FrameGrabbingControl)
      player.getControl("javax.media.control.FrameGrabbingControl");
      buf = fgc.grabFrame();
      
      // Convert it to an image
      btoi = new BufferToImage((VideoFormat)buf.getFormat());
      img = btoi.createImage(buf);
      
      // show the image
      imgpanel.setImage(img);
      
      // save image
      saveJPG(img,"c:\\test.jpg");
    }
  }
  
  class ImagePanel extends Panel 
  {
    public Image myimg = null;
    
    public ImagePanel() 
    {
      setLayout(null);
      setSize(320,240);
    }
    
    public void setImage(Image img) 
    {
      this.myimg = img;
      repaint();
    }
    
    public void paint(Graphics g) 
    {
      if (myimg != null) 
      {
        g.drawImage(myimg, 0, 0, this);
      }
    }
  }
  
 
  public static void saveJPG(Image img, String s)
  {
    BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = bi.createGraphics();
    g2.drawImage(img, null, null);
 
    FileOutputStream out = null;
    try
    { 
      out = new FileOutputStream(s); 
    }
    catch (java.io.FileNotFoundException io)
    { 
      System.out.println("File Not Found"); 
    }
    
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
    param.setQuality(0.5f,false);
    encoder.setJPEGEncodeParam(param);
    
    try 
    { 
      encoder.encode(bi); 
      out.close(); 
    }
    catch (java.io.IOException io) 
    {
      System.out.println("IOException"); 
    }
  }
  
}
Allerdings erscheinen in dem erscheinendem Fenster nicht die Bilder/Streams der Webcam!
Hängt das mit dem AWT-Swing Problem zusammen?

Viele Grüße
manu
 
Habe jetzt deinen Code nicht getestet, aber ein Applet kennt bspw. keine main()-Methode...

Deine Komponenten erben immer noch von AWT-Komponenten. Das solltest du erst mal umstellen.
Wenn du dein ImagePanel zu einem JPanel gemacht hast, musst du dann auch die paint()-Methode in paintComponent(Graphics g) umbenennen.

SwingCaptureer muss ein JPanel sein...

Und oben habe ich mich vertippt. Die Methode aus dem Applet muss init() heißen.
Und dann musst du noch eine Applet-Klasse schreiben, in die die init()-Methode gehört.
 
Ok danke, habs aber noch nicht ganz verstanden...

Jetzt sieht der Code so aus, aber irgendwas fehlt noch (?)!
Java:
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import javax.media.*;
import javax.media.format.*;
import javax.media.util.*;
import javax.media.control.*;
import javax.media.protocol.*;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import com.sun.image.codec.jpeg.*;
 
public class SwingCaptureer extends JApplet implements ActionListener 
{
  public static Player player = null;
  public CaptureDeviceInfo di = null;
  public MediaLocator ml = null;
  public JButton capture = null;
  public Buffer buf = null;
  public Image img = null;
  public VideoFormat vf = null;
  public BufferToImage btoi = null;
  public JPanel imgpanel = null;
  
  public void init() {
       Frame f = new Frame("SwingCapture");
    SwingCaptureer cf = new SwingCaptureer();
    
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
      playerclose();
      System.exit(0);}});
    
    f.add("Center",cf);
    f.pack();
    f.setSize(new Dimension(320,550));
    f.setVisible(true);
    
    
   setLayout(new BorderLayout());
   add(new SwingCaptureer());
 
    setLayout(new BorderLayout());
    setSize(320,550);
    
    imgpanel = new JPanel();
    capture = new JButton("Capture");
    capture.addActionListener(this);
    
    String str1 = "vfw:Logitech USB Video Camera:0";
    String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";
    di = CaptureDeviceManager.getDevice(str2);
    ml = di.getLocator();
    
    try 
    {
      player = Manager.createRealizedPlayer(ml);
      player.start();
      Component comp;
      
      if ((comp = player.getVisualComponent()) != null)
      {
        add(comp,BorderLayout.NORTH);
      }
      add(capture,BorderLayout.CENTER);
      add(imgpanel,BorderLayout.SOUTH);
    } 
    catch (Exception e) 
    {
      e.printStackTrace();
    }
  }
 
 
  
  public static void main(String[] args) 
  {
    Frame f = new Frame("SwingCapture");
    SwingCaptureer cf = new SwingCaptureer();
    
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
      playerclose();
      System.exit(0);}});
    
    f.add("Center",cf);
    f.pack();
    f.setSize(new Dimension(320,550));
    f.setVisible(true);
  }
  
  
  public static void playerclose() 
  {
    player.close();
    player.deallocate();
  }
  
 
  public void actionPerformed(ActionEvent e) 
  {
    JComponent c = (JComponent) e.getSource();
    
    if (c == capture) 
    {
      // Grab a frame
      FrameGrabbingControl fgc = (FrameGrabbingControl)
      player.getControl("javax.media.control.FrameGrabbingControl");
      buf = fgc.grabFrame();
      
      // Convert it to an image
      btoi = new BufferToImage((VideoFormat)buf.getFormat());
      img = btoi.createImage(buf);
      
      // show the image
      //imgpanel.setImage(img);
      
      // save image
      saveJPG(img,"c:\\test.jpg");
    }
  }
  
  class ImagePanel extends Panel 
  {
    public Image myimg = null;
    
    public ImagePanel() 
    {
      setLayout(null);
      setSize(320,240);
    }
    
    public void setImage(Image img) 
    {
      this.myimg = img;
      repaint();
    }
    
    public void paintComponent(Graphics g) 
    {
      if (myimg != null) 
      {
        g.drawImage(myimg, 0, 0, this);
      }
    }
  }
  
 
  public static void saveJPG(Image img, String s)
  {
    BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = bi.createGraphics();
    g2.drawImage(img, null, null);
 
    FileOutputStream out = null;
    try
    { 
      out = new FileOutputStream(s); 
    }
    catch (java.io.FileNotFoundException io)
    { 
      System.out.println("File Not Found"); 
    }
    
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
    param.setQuality(0.5f,false);
    encoder.setJPEGEncodeParam(param);
    
    try 
    { 
      encoder.encode(bi); 
      out.close(); 
    }
    catch (java.io.IOException io) 
    {
      System.out.println("IOException"); 
    }
  }
  
}

Viele Grüße
manu
 
Habe gerade kein JDK hier, kann also nichts umschreiben und kompilieren.
Vielleicht schaffe ich es heute Abend.

Aber wenn du noch mal von oben liest, solltest du eigendlich allein drauf kommen.
 

Neue Themen


Zurück
Oben