There is a FAQ on how to capture still images to JPEG,
(see http://tintoy.ncsa.uiuc.edu/~srp/java3d/faq.html)
but the code snippet provided there does not quite work. (It does not set
up the Raster). I appended a class that does the job...

The idea is to extend Canvas3D and write an own postSwap() method
that gets called after a frame has been swapped out of the frame
buffer to screen. Since it is not advised to call postSwap() directly,
(use repaint())  and since it gets called lots of times, what you do is to
set a flag (writeJPEG_ in the example) that triggers the capture
in postSwap().

To capture the image, you set up a Raster, get the GraphicsContext3D of
the Canvas3D, read the context into the raster and get its BufferedImage.
The rest (how to dump a JPEG from a BufferedImage) is example code taken
from some textbook.

cheers

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/     .       .  |          .
Peter Z. Kunszt                                    .      \|/     .
Bloomberg Center of Physics and Astronomy               ---*---
Johns Hopkins University Baltimore           .        .   /|\        .
                                                  .        |   .       .
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/               .

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.image.codec.jpeg.*;

/** Class CapturingCanvas3D, using the instructions from the Java3D 
    FAQ pages on how to capture a still image in jpeg format.

    A capture button would call a method that looks like


    public static void captureImage(CapturingCanvas3D MyCanvas3D) {
        MyCanvas3D.writeJPEG_ = true;
        MyCanvas3D.repaint();
    }


    Peter Z. Kunszt
    Johns Hopkins University
    Dept of Physics and Astronomy
    Baltimore MD
*/

public class CapturingCanvas3D extends Canvas3D  {

    public boolean writeJPEG_;
    private int postSwapCount_;

    public CapturingCanvas3D(GraphicsConfiguration gc) {
        super(gc);
        postSwapCount_ = 0;
    }

    public void postSwap() {
        if(writeJPEG_) {
            System.out.println("Writing JPEG");
            GraphicsContext3D  ctx = getGraphicsContext3D();
            // The raster components need all be set!
            Raster ras = new Raster(
                   new Point3f(-1.0f,-1.0f,-1.0f),
                   Raster.RASTER_COLOR,
                   0,0,
                   512,512,
                   new ImageComponent2D(
                             ImageComponent.FORMAT_RGB,
                             new BufferedImage(512,512,
                                               BufferedImage.TYPE_INT_RGB)),
                   null);

            ctx.readRaster(ras);

            // Now strip out the image info
            BufferedImage img = ras.getImage().getImage();

            // write that to disk....
            try {
                FileOutputStream out = new 
FileOutputStream("Capture"+postSwapCount_+".jpg");
                JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
                JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(img);
                param.setQuality(0.9f,false); // 90% qualith JPEG
                encoder.setJPEGEncodeParam(param);
                encoder.encode(img);
                writeJPEG_ = false;
                out.close();
            } catch ( IOException e ) {
                System.out.println("I/O exception!");
            }
            postSwapCount_++;
        }
    }
}

Reply via email to