Render into a BufferedImage

From JReality Wiki
Jump to: navigation, search

This code demonstrates how to render into a BufferedImage. It only works with de.jreality.jogl.Viewer, and it requires the path to be set up. See jreality/jni/README (Pure java support via SoftViewer is also planned for the future).

import java.awt.Component;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

import de.jreality.geometry.Primitives;
import de.jreality.io.JrSceneFactory;

public class RenderBufferedImageApp {

   public static void main(String[] args) throws InterruptedException {
		
      final de.jreality.jogl.Viewer v = new de.jreality.jogl.Viewer();
      v.setSceneRoot(Primitives.wireframeSphere());		
      v.setCameraPath(JrSceneFactory.getDefaultDesktopScene().getPath("cameraPath"));
	
      // The following 5 lines are to be deprecated when the backend gets cleaned up:
      JFrame frame = new JFrame();   
      frame.getContentPane().add((Component) v.getViewingComponent());	
      frame.setVisible(true);
      frame.setVisible(false);
      v.render();

      BufferedImage bi = v.renderOffscreen(1024,768);

      // Now we have a BufferedImage to do with what we like.
      // We could send it to a servlet, write it to a file, perform image processing, ...
      // but we'll just display it here for demo purposes. 
		
      JFrame jf = new JFrame("BufferedImage rendered");
      jf.getContentPane().add(new JLabel(new ImageIcon(bi)));
      jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      jf.pack();
      jf.setVisible(true);
   }
}



It is also possible to take a snapshot of the current window using pure Java. The following code is functionally similar to that above. The snapshot technique below relies on a scene being drawn and displayed on the physical screen and it uses JRobot to capture what is displayed. This may have some undesirable effects, for example if another window is overlapping, it may obscure the view and be captured instead. Therefore, we attempt to make the window briefly visible and on top while we take the snapshot.

public class CaptureBufferedImageApp {
   public static void main(String[]unused) {
      JRViewer v = JRViewer.createJRViewer(Primitives.wireframeSphere());
      v.startupLocal();
      final Viewer viewer = v.getViewer();
      JFrame frame = new JFrame("Active");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add((Component)viewer.getViewingComponent());
      frame.setSize(1024,768);
      frame.setLocation(5000,5000);
      frame.setVisible(true);
      frame.setLocation(5000,5000);
      frame.toFront();
      EventQueue.invokeLater(new Runnable() {
         public void run() {
            BufferedImage img = ImageUtility.captureScreenshot(viewer);

            // Now we have a BufferedImage to do with what we like.

            JFrame jf = new JFrame("BufferedImage captured");
            jf.getContentPane().add(new JLabel(new ImageIcon(img)));
            jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jf.pack();
            jf.setVisible(true);
         }
      });
   };
}