开发者

How to effectively render video in Java (AWT??)

In my project I've got a class FrameProducer firing events each time a video frame has been created. Each frame is an image returned as an java.awt.Image.BufferedImage object.

I've got 2 FrameProducer objects and would like to render BufferedImage's produced by them simultaneously on the screen. I would like the picture rendered on the screen to be scalable (that is, when I drag the application-window's corner the rendered video gets smaller or bigger).

How do you think this is best to be achieved?

I've considered using java.awt.Graphics2D embedded in an java.awt.Frame, but I don't know how such a thing can be done, or if this is the best choice. I just need this for algorithm visualisation, it doesn't need to be nice and shiny, just fast and easy. What would some suggestions or some ready code be that I could use?


Edit: OK, I implemented the solution as Rekin suggested, and it works. But as I'm not an Java expert and definitely not a Swing expert, I'd like to ask you for kind remarks on my code - I'm sure many will benefit from that in the future.

As I said, there is a FrameProducer (never mind the implementation):

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

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

Then there is also a FrameRenderer waiting for events from the FrameProducer (a simple observer-pattern implementation using 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());
        }
    }
}

And then there is also the thing that needs rework: the 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);
    }
}

It all gets initialised in the main method:

public class FrameAccessTest {
    public static void main(String[] args) {
        final FrameProducer frameGrabber开发者_StackOverflow = 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();
                }
            }
        });
    }
}

How do I implement initContents() in such a way, that all the video streams provided in MainFrame's constructor as FrameProducer[] get rendered in a row and that they are scalable?


I'd go with JPanel and overriding paintComponent method. In it I'd use Graphics2D.drawImage() giving width and height of container as a parameters to it.

The AWT approach seems closer to bare metal, but since JDK 6 brought a lot of improvements in Swing rendering pipeline, I would go the Swing & Java2D approach. It's accelerated by available hardware (using DirectDraw on Windows or OpenGL wherever possible) and hides a lot of low level details behind a nice API. For example You get double buffering for free.


Override the paintComponent method and use Graphics2D to draw your buffered image using drawImage. This method is overloaded and can be used to scale the image as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜