hi Guillaume,

Sorry I didn't answer this in the e-mail you sent directly to me... things have
been weird around here for the last couple of days, and I didn't get back to
answer you.

A couple of things.    First, as someone else pointed out, don't call postSwap()
directly, it is not meant to be called that way.   Set a value in another method
(like takeSnapshot) and let postSwap do all the work.  You don't need to have a
different thread to do
this, unless you expect to continually be writing out frames in realtime.
(I haven't tried that).

Another thing is that you shouldn't use the default values for JPEGImageEncoder.
Use JPEGEncodeParam and set the image
quality to the maximum value, otherwise it save the images at jpeg's lowest
quality level.


             FileOutputStream fos = new FileOutputStream(filename+frame+".jpg");
             BufferedOutputStream bos = new BufferedOutputStream(fos);

             JPEGImageEncoder jie = JPEGCodec.createJPEGEncoder(bos);
             JPEGEncodeParam param = jie.getDefaultJPEGEncodeParam(image);
             param.setQuality(1.0f,true);
             jie.setJPEGEncodeParam(param);
             jie.encode(image);

             bos.flush();
             fos.close();

A third thing to watch out for is that a while ago when we first wrote our code to
do this,  you couldn't capture images in postSwap(),
you had to do it in postRender().  I can't remember if this has been fixed yet,
but it was reported, so I'm sure it will be.  This only happened on the Windows
boxes we tried this on.

The fourth thing is that if you are ever going to run this on Solaris, be sure
that you're running the recommended configuration for Java.  Currently that's the
"reference" release.  If you use the production release (the one with native
threads), you'll get a black frame.  I spent a long time trying to figure out why
this was happening, and it ended up being an RTFM for me (who should have known
better).

Finally, I don't think JPEGImageEncoder is a publically exposed object anymore.
It is safe to use now for this release, but since its not a public object anymore
it could change or go away.

Steve
PS.  The RecordableCanvas3D object in NCSA Portfolio
http://havefun.ncsa.uiuc.edu/Java3D/portfolio/  has the functionality that you
want.  It's a subclass of Canvas3D, so it should work just fine.

Guillaume Bilodeau wrote:

> Hi,
>
>         I am working on a 3D object viewer, in Java3D.  One of the
> functionalities I'd
> like to implement is the capability to take a snapshot of the model, that is
> copying the content of the Canvas3D to a JPEG file.  I currently have a class
> that extends Canvas3D, Viewer3D, that overrides the postSwap() method, in which
> I do the processing.  Unfortunately, the call to the readRaster(Raster) method
> crashes opengl32.dll every time.  Could you tell me what is wrong with my code?
> I am using Java 2 and Java3D 1.1, all this running on Windows 95.
>
>         Thank you very much!
>
> ----------
> /* Code */
>
> // the raster that will contain the captured image
> private Raster rasSnapshot;
>
> // this is set to true when a snapshot must be taken
> private boolean bTakeSnapshot = false;
>
> public void takeSnapshot(String filename) {
>     bTakeSnapshot = true;
>     postSwap();
>
>     while (bTakeSnapshot)
>         Thread.currentThread().yield();
>
>     BufferedImage bi = rasSnapshot.getImage().getImage();
>     FileOutputStream fOut = null;
>     try {
>         fOut = new FileOutputStream(filename);
>         JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fOut);
>         encoder.encode(bi);
>     } catch (ImageFormatException ife) {
>     } catch (IOException ioe) {
>     } finally {
>         if (fOut != null) {
>             try {
>                 fOut.close();
>             } catch (IOException ioe2) {
>             }
>         }
>     }
> }
>
> public void postSwap() {
>     // original method
>     super.postSwap();
>
>    // takes a snapshot if requested
>     if (bTakeSnapshot) {
>         bTakeSnapshot = false;
>
>         Dimension d = getSize();
>         BufferedImage bImage = new BufferedImage(d.width, d.height,
>             BufferedImage.TYPE_INT_ARGB);
>         ImageComponent2D imgComp = new ImageComponent2D(
>             ImageComponent2D.FORMAT_RGB, bImage);
>         rasSnapshot = new Raster(new Point3f(), Raster.RASTER_COLOR,
>             0, 0, d.width, d.height, imgComp, null);
>
> System.out.println("Before readRaster()!");
>         getGraphicsContext3D().readRaster(rasSnapshot);
> System.out.println("After readRaster()!");
>     }
> }

--
Steve Pietrowicz - [EMAIL PROTECTED]    Project Manager - NCSA Java 3D Group

NCSA Portfolio:      http://havefun.ncsa.uiuc.edu/Java3D/portfolio/
   New Beta 2a release!  New Loaders, record and replay of your
   Java 3D apps and more! Freely available for non-commercial use!
You Build It VR:     http://havefun.ncsa.uiuc.edu/Java3D/YouBuildItVR/
   Build your own multi-user virtual worlds with no programming experience!
The Java3D FAQ:      http://tintoy.ncsa.uiuc.edu/~srp/java3d/faq.html
Java News Network:   http://tintoy.ncsa.uiuc.edu/~srp/java/javanews.html



=====================================================================
To subscribe/unsubscribe, send mail to [EMAIL PROTECTED]
Java 3D Home Page: http://java.sun.com/products/java-media/3D/

Reply via email to