0

Java Media Framework (JMF) を使用して Web カメラから画像を抽出する短いプログラムを作成しています。

多くの人が以前に抱えていた問題に遭遇したようですが、明確に定式化された解決策は存在しません。私は日食を使用していますが、私のプログラムは正常に動作します。jmf.jar を外部ライブラリとして追加しました。

さて、問題は、プログラムをjarとしてエクスポートすると、コマンドラインで実行すると次のエラーが発生することです。

Exception in thread "main" java.lang.NullPointerException
    at recorder.SimpleRecorder.<init>(SimpleRecorder.java:46)
    at recorder.SimpleRecorder.main(SimpleRecorder.java:67)

46行目はml = di.getLocator();. (以下のコードを含めました。)

これは、jmf.jar を外部ライブラリとして追加せずに Eclipse でプログラムを実行しようとしたときに発生するエラーと同じです。

このようなインターネット上のいくつかのリソース

https://forums.oracle.com/forums/thread.jspa?threadID=1277297

ファイル jmf.properties が問題の原因であることを示唆しています。したがって、上記のリソースが提案したいくつかのことを試しました。

  • jmf.properties ファイルのパスを jar のマニフェストに追加します。その後、マニフェストは次のようになります。

    マニフェスト バージョン: 1.0

    クラスパス: . 「C:\Program Files (x86)\JMF2.1.1e\lib\jmf.properties」

    Main-Class:recorder.SimpleRecorder

    それがマニフェストにパスを追加する正しい方法かどうかはわかりません。

  • また、フォルダー C:\Program Files (x86)\Java\jre7\lib から jmf.jar を削除しようとしました。これは、jmf が 2 回使用可能であったため、eclipse で問題が発生するように思われたためですjmf.jar を外部ライブラリとして追加すると、上記のエラーが発生します)。

  • jar ファイルが置かれているフォルダーに jmf.properties を追加すると、別のエラーが発生しました。

    スレッド「VFW 要求スレッド」の例外 java.lang.UnsatisfiedLinkError: JMFSecurityManager: java.lang.UnsatisfiedLinkError: com.sun.media.JMFSecurityManager.loadLibrary(JMFSecurityManager.java:206) の java.library.path に jmvfw がありません。 sun.media.protocol.vfw.VFWCapture.(VFWCapture.java:19) com.sun.media.protocol.vfw.VFWSourceStream.doConnect(VFWSourceStream.java:241) com.sun.media.protocol.vfw.VFWSourceStream .run (VFWSourceStream.java:763) で java.lang.Thread.run (不明なソース)

  • jmf.properties ファイルを jar 内を含む他の場所にコピーしても (上記のリソースで提案されているように)、何の効果もありませんでした。

誰かがそれを解決する方法を知っていることを願っています - より多くの情報を提供できれば幸いです.

ありがとう、

ジョナス

package recorder;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;

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.JFrame;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class SimpleRecorder extends JFrame{

public static Player player = null;
public CaptureDeviceInfo di = null;
public MediaLocator ml = null;
public Buffer buf = null;
public Image img = null;
public VideoFormat vf = null;
public BufferToImage btoi = null;

public SimpleRecorder(String title) {
    super(title);

    String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";
    di = CaptureDeviceManager.getDevice(str2);

    if(di == null) System.out.println("di is null.");

    ml = di.getLocator();

    try 
    {
      player = Manager.createRealizedPlayer(ml);
      player.start();
      Component comp;

      if ((comp = player.getVisualComponent()) != null)
      {
        add(comp,BorderLayout.CENTER);
      }

    } 
    catch (Exception e) 
    {
      e.printStackTrace();
    }
}

public static void main(String[] args){
    SimpleRecorder frame = new SimpleRecorder("Simple Recorder");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setSize(335,275);
    frame.setLayout(new BorderLayout());
    frame.setVisible(true);

    frame.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
          playerclose();
          System.exit(0);}});

    System.out.println("Waiting for camera to get ready...");

    try {
        Thread.sleep(5000);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    System.out.println("Start recording...");
    while(true){

        frame.recordImage();

        try {
            Thread.sleep(350);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }   
}

private void recordImage(){

     // 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);

      // Get current directory
      String currentDir = new File("./Extracted_Image.jpg").getAbsolutePath();

      // save image
      saveJPG(img,currentDir);
}

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"); 
    }

    if(out == null) System.out.println("Could not create file output stream.");

    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"); 
    }
  }

public static void playerclose() 
  {
    player.close();
    player.deallocate();
  }

}

4

1 に答える 1

0

チェックすることの 1 つは、eclipse.ini です。ワークスペースのインストール済み jre が eclipse.ini で指定された vm と一致しないという問題が発生しました。ini が 1.6 を使用し、workspace が 1.7 を使用する場合、一部の Eclipse プラグインは 1.6 ツールで 1.7 バイトコードまたはソースを処理しようとし、さまざまな問題が発生する可能性があります。

  • \eclipse.ini を編集
  • VM が期待されるバージョンに設定されていることを確認する

    -vm c:/java/jdk1.7.0_05/jre/bin/server/jvm.dll

于 2013-02-08T17:12:01.450 に答える