"Casteel, Don" wrote:
> I'm posting this class for everyone who needs to print and/or capture from
> their Canvas3D objects. As I was trying to figure out how to do it, I saw
> many messages in the interest group archive on the subject asking for help,
> I hope this helps.
>
> First I must acknowledge the work done by:
>
> Peter Z. Kunszt
> Johns Hopkins University
> Dept of Physics and Astronomy
> Baltimore MD
>
> I worked from his already published CapturingCanvas3D class. I've made some
> minor revisions to his code by letting the captured image automatically size
> itself to the Canvas3D with "this.getWidth()" & "this.getHeight()" methods.
>
> I've then attempted to add printing capability. Printing does work, however
> there are bugs to be resolved. Primarily the printed image seems to be
> clipping only part of the captured image, but the captured-saved images are
> correct. I've tested it with Windows95 to a dedicated printer & WindowsNT to
> a network printer, and it seems to work ok for both, but is slower on the
> Win95 system.
>
> I request that if anyone finds improvements to the code, that they post it
> to the group. Perhaps our friends at SUN can further develop this and make
> it part of the next release of Java3D. I'd also like to see additional file
> formats supported like GIF and TARGA.
>
> Please let me know what you think.
Don, I fixed the clipping problem you were having. Basically, before the image is
drawn you have to:
g2d.translate(pf.getImageableX(), pf.getImageableY());
and then nothing gets clipped. Look for it right before the call to drawObject().
I'll get this version of CapturingCanvas3D updated in the FAQ too.
I'm attaching a copy of the updated .java file you sent, and a modified copy of
HelloUniverse.java that demonstrates how this all works.
Now, my question is, how can we reduce the size of the file that gets sent to the
printer?? The dang thing registered as a 32 MB file when it was sent!
Steve
--
Steve Pietrowicz - [EMAIL PROTECTED] Project Manager - NCSA Java 3D Group
NCSA Portfolio 1.3 beta 3: http://havefun.ncsa.uiuc.edu/Java3D/portfolio/
New Loaders, turn your Canvas3D into a JPEG, new InputDevices 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
Astro3D: Java 3D Astronomy - http://havefun.ncsa.uiuc.edu/Java3D/Astro3D/
/*
* @(#)HelloUniverse.java 1.48 99/05/20 14:07:00
*
* Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.event.*;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
public class HelloUniverse extends Applet {
public BranchGroup createSceneGraph() {
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
// Create the transform group node and initialize it to the
// identity. Enable the TRANSFORM_WRITE capability so that
// our behavior code can modify it at runtime. Add it to the
// root of the subgraph.
TransformGroup objTrans = new TransformGroup();
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRoot.addChild(objTrans);
// Create a simple shape leaf node, add it to the scene graph.
objTrans.addChild(new ColorCube(0.4));
// Create a new Behavior object that will perform the desired
// operation on the specified transform object and add it into
// the scene graph.
AxisAngle4f axisAngle = new AxisAngle4f(0.0f, 0.0f, 1.0f,
-(float)Math.PI / 2.0f);
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0,
4000, 0, 0,
0, 0, 0);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, objTrans, yAxis,
0.0f, (float) Math.PI*2.0f);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
rotator.setSchedulingBounds(bounds);
objTrans.addChild(rotator);
// Have Java 3D perform optimizations on this scene graph.
objRoot.compile();
return objRoot;
}
public HelloUniverse() {
setLayout(new BorderLayout());
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
PrintCaptureCanvas3D c = new PrintCaptureCanvas3D(config);
Button button = new Button("Print");
button.addActionListener(new PrintActionListener(c));
add("North", button);
add("Center", c);
// Create a simple scene and attach it to the virtual universe
BranchGroup scene = createSceneGraph();
SimpleUniverse u = new SimpleUniverse(c);
// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
//
// The following allows HelloUniverse to be run as an application
// as well as an applet
//
public static void main(String[] args) {
new MainFrame(new HelloUniverse(), 256, 256);
}
}
class PrintActionListener implements ActionListener {
PrintCaptureCanvas3D canvas;
public PrintActionListener(PrintCaptureCanvas3D c) {
canvas = c;
}
public void actionPerformed(ActionEvent e) {
canvas.writeJPEG_ = true;
canvas.saveJPEG_ = false;
canvas.repaint();
}
}
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.image.*;
import java.awt.print.*;
import java.awt.print.PrinterJob;
import java.awt.print.PrinterGraphics;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.io.*;
import java.net.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import com.sun.image.codec.jpeg.*;
/** Class PrintCaptureCanvas3D, 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(PrintCaptureCanvas3D c)
{
c.writeJPEG_ = true;
c.saveJPEG_ = true;
c.repaint();
};
A print button would call a method that looks like
public static void printJPGImage(PrintCaptureCanvas3D c)
{
c.writeJPEG_ = true;
c.saveJPEG_ = false;
c.repaint();
};
Peter Z. Kunszt
Johns Hopkins University
Dept of Physics and Astronomy
Baltimore MD
Working from Mr. Kunszt's posted class, the following enhancements were added:
BufferedImage img; was made global to the class.
The image width was made dynamic using this.getWidth() & this.getHeight() methods.
Printing capability was added (this is still buggy however)
Don Casteel 10/24/1999
[EMAIL PROTECTED]
*/
public class PrintCaptureCanvas3D extends Canvas3D implements Printable, ImageObserver
{
public boolean writeJPEG_;
private int postSwapCount_;
public boolean saveJPEG_;
BufferedImage img;
FileDialog fileDialog;
File file;
File directory;
public PrintCaptureCanvas3D(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),
javax.media.j3d.Raster.RASTER_COLOR,
0,0,
this.getWidth(),this.getHeight(),
new ImageComponent2D
(
ImageComponent.FORMAT_RGB,
new BufferedImage
(
this.getWidth(),
this.getHeight(),
BufferedImage.TYPE_INT_RGB
)
),
null
);
ctx.readRaster(ras);
// Now strip out the image info
img = ras.getImage().getImage();
// write that to disk....
if(saveJPEG_)
{
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!");
};
}
else
{
printMethod();
writeJPEG_ = false;
};
postSwapCount_++;
}
};
public int print(Graphics g, PageFormat pf, int pi)
throws PrinterException
{
if (pi >= 1)
{
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
drawObject(g2d);
return Printable.PAGE_EXISTS;
};
public void drawObject(Graphics2D g2d)
{
try
{
g2d.drawImage(img,new AffineTransform(), this);
}
catch (Exception ex)
{
ex.printStackTrace();
};
};
public void printMethod()
{
System.out.println("Print Method Called");
PrinterJob printJob = PrinterJob.getPrinterJob();
PageFormat pageFormat = printJob.defaultPage();
pageFormat = printJob.validatePage(pageFormat);
printJob.setPrintable(this);
if (printJob.printDialog())
{
try
{
printJob.print();
}
catch (Exception ex)
{
System.out.println("Exception Caught");
ex.printStackTrace();
};
};
};
}