I found the bug :)  The raster size was wrong, off by one.  Once I fixed
that it worked.  Also the technique is a complete success.  You can read the
raster with a depth component from an offscreen buffer and then adjust alpha
values in the image using the depth information.  Makes a perfect mask.

Dave Yazel

----- Original Message -----
From: David Yazel <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Monday, May 28, 2001 1:48 PM
Subject: [JAVA3D] Offscreen buffer -> rasters


Hello all...

I am trying something funky...  The idea is to read into an offscreen
buffer, then read into a raster with a depth component.  I would then use
the depth component to create a mask for the image and turn that into an
alpha mask.  This should allow me to create an object only image with the
background masked out. (In theory).

The problem is that the raster I read is all messed up, slanted to the right
and fliped on the diagonal.

Is it possible to do this:

 GraphicsContext3D  ctx = getGraphicsContext3D();
      ctx.readRaster(raster);
      pic = raster.getImage().getImage();

On a canvas that is built for an offscreen buffer?

The raster is built like this:

      // create a raster for grabbing frames.  Set it up to have an integer
z-buffer

      rbuffer = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
      ImageComponent2D rb = new ImageComponent2D(ib.FORMAT_RGB,rbuffer);
      DepthComponentInt dc = new DepthComponentInt(width,height);
      raster = new Raster(new Point3f(-1.0f,-1.0f,-1.0f),
        Raster.RASTER_COLOR_DEPTH,
        0,0,
        width-1,height-1,rb,dc);

The width and height of the raster buffer is the same size as the size of
the offscreen buffer.  Perhaps the error is in the raster construction?

Here is all the code:

package com.xith.java3d.canvas;

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

/**
 * PictureGrabber is designed to be used as an offscreen canvas which can
 * take a picture of a model with an alpha masked background.  This is done
 * by reading the canvas into a raster with a depth componant, and then
 * checking which pixels were written too and which were not.
 *
 * Copyright:  Copyright (c) 2000,2001
 * Company:    Teseract Software, LLP
 * @author David Yazel
 *
 */

public class PictureGrabber extends Canvas3D {

   private boolean takePicture = false;
   private int width;
   private int height;
   private ImageComponent2D offscreenBuffer;
   private BufferedImage pic;
   private BufferedImage rbuffer;
   private Raster raster;

   private static GraphicsConfiguration getOffscreenGraphicsConfig() {

      GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
      GraphicsConfiguration gcfg =
              GraphicsEnvironment.getLocalGraphicsEnvironment().
              getDefaultScreenDevice().getBestConfiguration(template);
      return gcfg;
   }

   private PictureGrabber( GraphicsConfiguration c ) {
      super(c,true);
   }

   public PictureGrabber(GraphicsConfiguration config, int width, int
height) {

      super(config,true);
      this.width = width;
      this.height = height;
      this.getScreen3D().setSize(width,height);
      this.getScreen3D().setPhysicalScreenWidth(0.0254/90.0*width);
      this.getScreen3D().setPhysicalScreenHeight(0.0254/90.0*height);

      // create the offscreen buffer

      pic = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
      ImageComponent2D ib = new ImageComponent2D(ib.FORMAT_RGBA,pic);
      this.setOffScreenBuffer(ib);

      // create a raster for grabbing frames.  Set it up to have an integer
z-buffer

      rbuffer = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
      ImageComponent2D rb = new ImageComponent2D(ib.FORMAT_RGB,rbuffer);
      DepthComponentInt dc = new DepthComponentInt(width,height);
      raster = new Raster(new Point3f(-1.0f,-1.0f,-1.0f),
        Raster.RASTER_COLOR_DEPTH,
        0,0,
        width-1,height-1,rb,dc);

   }

   /**
    * This will take the picture immediatly by forcing a frame draw.  This
    * is only acceptable if the canvas is an offscreen canvas.
    */

   public BufferedImage takePicture() {
      this.renderOffScreenBuffer();
      this.waitForOffScreenRendering();
      /* this works... its returns an image
      BufferedImage bImage = this.getOffScreenBuffer().getImage();
       return bImage;
     */

     return pic;
   }

   /**
    * Our post swap is used to grab an image of the canvas into a raster and
then
    * use the depth component to mask out the background from the image.
    */
   public void postSwap() {

      GraphicsContext3D  ctx = getGraphicsContext3D();
      ctx.readRaster(raster);
      pic = raster.getImage().getImage();

      System.out.println("Got thumbnail");
   }

}

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to