2010-10-11 29 views
2

在我的項目中,每次創建視頻幀時都會觸發類別FrameProducer射擊事件。每個幀都是作爲java.awt.Image.BufferedImage對象返回的圖像。如何在Java中有效地渲染視頻(AWT ??)

我有2 FrameProducer對象,並想在屏幕上同時生成BufferedImage's。我想在屏幕上呈現的圖片是可縮放(也就是說,當我拖動應用程序窗口的角落時,呈現的視頻變得更小或更大)。

您認爲最好的實現方式是?

我已經考慮過使用嵌入在java.awt.Frame中的java.awt.Graphics2D,但我不知道如何做這樣的事情,或者如果這是最好的選擇。我只需要這個算法可視化,它不需要很好,有光澤,只需要快速和簡單。我可以使用哪些建議或準備好的代碼?


編輯: OK,我實現瞭解決方案Rekin建議,和它的作品。但由於我不是Java專家,絕對不是專家,所以我想問你一些關於我的代碼的好評 - 我相信很多人都會從中受益。

正如我所說的,是有FrameProducer(心中永遠的實現):

public abstract class FrameProducer extends Observable { 
    public abstract BufferedImage getFrame(); 

    public void fireEvent() { 
     setChanged(); 
     notifyObservers(); 
    } 
} 

然後還有一個FrameRendererFrameProducer(使用java.util簡單的觀察者模式實現)等待事件:

public class FrameRenderer extends JPanel implements Observer { 
    private BufferedImage frame; 
    @Override 
    protected void paintComponent(Graphics g) { 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.drawImage(frame, null, 0, 0); 
     g2d.dispose(); 
    } 
    @Override 
    public void update(Observable observable, Object arg) { 
     System.out.println("Cought an event from " + observable.getClass()); 
     if (observable instanceof FrameProducer) { 
      frame = ((FrameProducer) observable).getFrame(); 
      paint(getGraphics()); 
     } 
    } 
} 

然後還有需要返工的東西:MainFrame

public class MainFrame extends JFrame { 

    FrameProducer[] producers; 

    public MainFrame(FrameProducer[] producers) { 
     this.setTitle("Playing what you feed."); 
     this.producers = producers; 
     initContents(); 
     setVisible(true); 
    } 

    private void initContents() { 
     FrameRenderer renderer = new FrameRenderer(); 
     renderer.setLocation(0, 0); 
     this.add(renderer); 
     producers[0].addObserver(renderer); 
    } 
} 

這一切又在main方法初始化:

public class FrameAccessTest { 
    public static void main(String[] args) { 
     final FrameProducer frameGrabber = new CameraFrameGrabber("vfw://0"); 

     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        MainFrame mainFrame = 
         new MainFrame(new FrameProducer[] {frameGrabber}); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 

如何實現initContents()以這樣的方式,在MainFrame's構造提供爲FrameProducer[]所有的視頻流得到渲染一排,他們是可擴展的?

回答

2

我會用JPanel和覆蓋paintComponent方法。在這裏我使用Graphics2D.drawImage()給容器的寬度和高度作爲參數。

AWT方法似乎更接近裸機,但由於JDK 6在Swing渲染管道中帶來了很多改進,我將採用Swing & Java2D方法。它通過可用的硬件加速(儘可能在Windows或OpenGL上使用DirectDraw),並在良好的API背後隱藏很多低級細節。例如,你可以免費獲得雙緩衝。

+0

謝謝你的回答。我會給它一個鏡頭,並在完成後發佈我的代碼,也許你會有任何意見。 – mmm 2010-10-11 13:19:45

+0

很高興有任何幫助。我多次面臨類似的挑戰。也從中獲得了一點OpenGL的專業知識,所以不要猶豫,問。 – Rekin 2010-10-11 13:39:56

+0

好的,我添加了我的代碼。請看看,如果可以的話,請。 – mmm 2010-10-12 08:12:27

0

重寫paintComponent方法並使用Graphics2D使用drawImage繪製緩衝圖像。該方法過載,也可用於縮放圖像。