2010-10-11 122 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绘制缓冲图像。该方法过载,也可用于缩放图像。