View Javadoc
1 /***************************************************************************** 2 * Virtual Mockup for Machine Vision 3 * Copyright (C) 2001-2003 Fabio R. de Miranda, Joćo E. Kogler Jr., 4 * Carlos S. Santos. 5 * Virtual Mockup for Machine Vision Project funded by SENAC-SP 6 * 7 * Permission is granted to redistribute and/or modify this 8 * software under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This software is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License (http://www.gnu.org/copyleft/lesser.html) 16 * for more details. 17 * 18 *****************************************************************************/ 19 20 package camera3d; 21 22 import com.sun.j3d.utils.applet.MainFrame; 23 import com.sun.j3d.utils.image.*; 24 import java.awt.print.*; 25 import java.awt.print.PrinterJob; 26 import java.awt.print.PrinterGraphics; 27 import java.awt.*; 28 import java.awt.image.BufferedImage; 29 import java.awt.Image; 30 import java.awt.image.ImageObserver; 31 import java.io.*; 32 import java.net.*; 33 import javax.media.j3d.*; 34 import javax.vecmath.*; 35 import java.awt.geom.AffineTransform; 36 import java.awt.image.BufferedImage; 37 import com.sun.image.codec.jpeg.*; 38 import java.awt.Color; 39 40 import javax.imageio.*; 41 42 /*** 43 * A Canvas3D that provides the capability for saving snapshot images. Optionally, 44 * the size of the saved image can be selected, so it differs from the resolution shown 45 * on screen.<BR> 46 * Adapted from Don Casteel's PrintCaptureCanvas3D.java (changes made refer to resolution-changing 47 * code before saving).<BR> 48 * Don Casteel 10/24/1999<BR> 49 * Dcasteel@usit.net<BR> 50 * @author Fabio Roberto de Miranda 51 */ 52 class SaverCanvas3D extends Canvas3D implements ImageObserver { 53 /*** JPEG file type. */ 54 static final int JPEG = 0; 55 56 /*** Indicates the type of image file to be created when the frame is saved.*/ 57 private int filetype; 58 59 private BufferedImage img; 60 private BufferedImage robotImg; 61 private boolean saveFrame = false; 62 private Raster ras; 63 private GraphicsContext3D ctx; 64 private String message = ""; 65 66 private int sizeX=320; 67 private int sizeY=240; 68 69 70 71 private String filename = "capture"; 72 private boolean hasMessage = false; 73 private boolean drawAxes = false; 74 75 private Color green; 76 77 private OffScreenCanvas3D offCanvas; 78 private boolean imageReady = false; 79 80 private Transform3D vworldToImagePlateT3D = new Transform3D(); 81 /* Storage for points received from outer world*/ 82 private Point3d axisCenter = new Point3d(0.0, 0.0, 0.0); 83 private Point3d axisX = new Point3d(50.0, 0.0, 0.0); 84 private Point3d axisY = new Point3d(0.0, 50.0, 0.0); 85 private Point3d axisZ = new Point3d(0.0, 0.0, 50.0); 86 87 /* Points transformed to image plate coordinates*/ 88 private Point3d ipAxisCenter = new Point3d(0.0, 0.0, 0.0); 89 private Point3d ipAxisX = new Point3d(10.0, 0.0, 0.0); 90 private Point3d ipAxisY = new Point3d(0.0, 10.0, 0.0); 91 private Point3d ipAxisZ = new Point3d(0.0, 0.0, 10.0); 92 93 private Point2d centerP2d = new Point2d(); 94 private Point2d xP2d = new Point2d(); 95 private Point2d yP2d = new Point2d(); 96 private Point2d zP2d = new Point2d(); 97 98 private int axisLength = 25; 99 100 private boolean saveOffFrame = true; 101 102 public SaverCanvas3D(GraphicsConfiguration gc){ 103 super(gc); 104 ctx = getGraphicsContext3D(); 105 green = new Color(0,100,40); 106 offCanvas = new OffScreenCanvas3D(gc, true); 107 } 108 109 /*** 110 * Canvas3D uses the addNotify callback to track when it is added to a container. 111 */ 112 public void addNotify(){ 113 super.addNotify(); 114 } 115 116 /*** 117 * 118 */ 119 public void saveFrame(String filename){ 120 this.filename = filename; 121 saveFrame = true; 122 } 123 124 /*** 125 * Saves the last rendered frame to an image file. This method allows setting the size 126 * of the image file. 127 * @param filename name of file to be saved. 128 * @param filetype type of file (currently only JPEG is supported). 129 * @param width width of the image (pixels). 130 * @param height height of image (pixels). 131 */ 132 public void saveFrame(String filename, int filetype, int width, int height){ 133 this.filename = filename; 134 this.filetype = filetype; 135 saveOffFrame = true; 136 View view = this.getView(); 137 138 view.addCanvas3D(this.offCanvas); 139 offCanvas.setSize(width, height); 140 offCanvas.getScreen3D().setSize(width, height); 141 offCanvas.getScreen3D().setPhysicalScreenHeight(this.getScreen3D().getPhysicalScreenHeight()); 142 offCanvas.getScreen3D().setPhysicalScreenWidth(this.getScreen3D().getPhysicalScreenWidth()); 143 offCanvas.repaint(); 144 145 //view.stopView(); 146 this.setImageReady(); 147 //view.startView(); 148 if(this.filetype==SaverCanvas3D.JPEG){ 149 offCanvas.print(true, filename, width, height); 150 } 151 } 152 153 public OffScreenCanvas3D getOffScreenCanvas3D(){ 154 return this.offCanvas; 155 } 156 157 public void postSwap(){ 158 // The raster components need all be set! 159 if (saveFrame){ 160 saveFrame = false; 161 ras = new Raster( 162 new Point3f(-1.0f,-1.0f,-1.0f), 163 javax.media.j3d.Raster.RASTER_COLOR, 164 0,0, 165 this.getWidth(),this.getHeight(), 166 new ImageComponent2D 167 ( 168 ImageComponent.FORMAT_RGB, 169 new BufferedImage 170 ( 171 this.getWidth(), 172 this.getHeight(), 173 BufferedImage.TYPE_INT_RGB 174 ) 175 ), 176 null 177 ); 178 179 sizeX = this.getWidth(); 180 sizeY = this.getHeight(); 181 182 ctx.readRaster(ras); 183 img = ras.getImage().getImage(); 184 robotImg = makeBufferedImage(img.getScaledInstance(sizeX, sizeY,Image.SCALE_SMOOTH)); 185 System.out.println("Saving file "+filename); 186 saveJPEG(robotImg); 187 } 188 189 if (saveOffFrame){ 190 } 191 } 192 193 194 195 public void drawObject(Graphics2D g2d) { 196 try { 197 g2d.drawImage(img,new AffineTransform(), this); 198 } catch (Exception ex) { 199 ex.printStackTrace(); 200 } 201 } 202 203 public void setImageSize(int x, int y){ 204 this.sizeX = x; 205 this.sizeY = y; 206 } 207 208 /*** 209 * 210 */ 211 private void saveJPEG(BufferedImage img){ 212 try { 213 FileOutputStream out = new FileOutputStream(filename); 214 // new code that uses ImageIO, since JDK1.4 215 boolean b = ImageIO.write(img,"jpeg",out); 216 if(!b) debugln("Could not find appropriate writer"); 217 218 // old code that used JPEG* classes 219 //JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 220 //JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(img); 221 //param.setQuality(1.0f,false); // 100% quality JPEG 222 //encoder.setJPEGEncodeParam(param); 223 //encoder.encode(img); 224 //out.close(); 225 //printRGBValues(img); 226 } catch ( IOException e ) { 227 System.out.println("I/O exception!"); 228 } 229 } 230 231 public BufferedImage makeBufferedImage(Image source) { 232 int width = source.getWidth(this); 233 int height = source.getHeight(this); 234 if (width == -1 || height == -1) { 235 System.out.println("No width or height on source image."); 236 return null; 237 } 238 // Create a BufferedImage from the given Image. 239 BufferedImage bufferedImage = new BufferedImage(width, height, 240 BufferedImage.TYPE_INT_RGB); 241 Graphics2D g = bufferedImage.createGraphics(); 242 g.drawImage(source, null, null); 243 return bufferedImage; 244 } 245 246 public void printRGBValues(BufferedImage buff){ 247 int xMax = buff.getWidth(); 248 int yMax = buff.getHeight(); 249 for(int i=0; i< yMax; i++){ 250 for(int j=0; j<xMax; j++){ 251 System.out.print(buff.getRGB(j,i)+" ,"); 252 } 253 System.out.println(); 254 } 255 } 256 257 int counter; 258 public void postRender(){ 259 if (hasMessage==true){ 260 this.getGraphics2D().drawString(message, this.getWidth()/4, this.getHeight()/2); 261 this.getGraphics2D().flush(true); 262 } 263 counter++; 264 if ((drawAxes)&&(counter % 1 == 0)){ 265 convertPointsToPlate(); 266 if ((centerP2d.x > 0)&&(centerP2d.x < this.getWidth())&&(centerP2d.y > 0)&&(centerP2d.y < this.getHeight())){ 267 printPixelPoints(); 268 debugln("Height" + this.getHeight()); 269 debugln("Width" + this.getWidth()); 270 //if ((xP2d.x > 0)&&(xP2d.x < this.getWidth())&&(xP2d.y > 0)&&(xP2d.y > this.getHeight())){ 271 this.getGraphics2D().drawLine((int)centerP2d.x, (int)centerP2d.y, (int)xP2d.x, (int)xP2d.y); 272 this.getGraphics2D().drawString("X", (int)xP2d.x + 2, (int)xP2d.y + 2); 273 //} 274 //if ((yP2d.x > 0)&&(yP2d.x < this.getWidth())&&(yP2d.y > 0)&&(yP2d.y > this.getHeight())){ 275 this.getGraphics2D().drawLine((int)centerP2d.x, (int)centerP2d.y, (int)yP2d.x, (int)yP2d.y); 276 this.getGraphics2D().drawString("Y", (int)yP2d.x + 2, (int)yP2d.y + 2); 277 //} 278 //if ((zP2d.x > 0)&&(zP2d.x < this.getWidth())&&(zP2d.y > 0)&&(zP2d.y > this.getHeight())){ 279 this.getGraphics2D().drawLine((int)centerP2d.x, (int)centerP2d.y, (int)zP2d.x, (int)zP2d.y); 280 this.getGraphics2D().drawString("Z", (int)zP2d.x + 2, (int)zP2d.y + 2); 281 //} 282 this.getGraphics2D().flush(true); 283 } 284 } 285 } 286 287 /*** 288 * Turns on the exhibition of a text message on the canvas. 289 * @param message text to be displayed. 290 */ 291 public void enableMessage(String message){ 292 // 293 this.message = message; 294 hasMessage = true; 295 //this.getGraphics2D().setColor(green); 296 } 297 298 /*** 299 * Disables the exhibition of messages on the canvas. 300 */ 301 public void disableMessage(){ 302 hasMessage = false; 303 } 304 305 public void transformToImagePlate(Point3d center, Point3d x, Point3d y, Point3d z){ 306 vworldToImagePlateT3D.transform(center, ipAxisCenter); 307 vworldToImagePlateT3D.transform(x, ipAxisX); 308 vworldToImagePlateT3D.transform(y, ipAxisY); 309 vworldToImagePlateT3D.transform(z, ipAxisZ); 310 } 311 312 void setAxisPoints(Point3d center, Point3d x, Point3d y, Point3d z){ 313 drawAxes = true; 314 // Locally store the values 315 axisCenter.set(center); 316 axisX.set(x); 317 axisY.set(y); 318 axisZ.set(z); 319 } 320 321 private void convertPointsToPlate(){ 322 getVworldToImagePlate(vworldToImagePlateT3D); 323 transformToImagePlate(axisCenter, axisX, axisY, axisZ); 324 this.getPixelLocationFromImagePlate(ipAxisCenter, centerP2d); 325 this.getPixelLocationFromImagePlate(ipAxisX, xP2d); 326 this.getPixelLocationFromImagePlate(ipAxisY, yP2d); 327 this.getPixelLocationFromImagePlate(ipAxisZ, zP2d); 328 lengthenSegment(centerP2d, xP2d, axisLength); 329 lengthenSegment(centerP2d, yP2d, axisLength); 330 lengthenSegment(centerP2d, zP2d, axisLength); 331 } 332 333 private void lengthenSegment(Point2d begin, Point2d end, int length){ 334 // Observes if a line from begin to end has a length that matches 335 // given length 336 //debugln("Pre-lengthen: ("+end.x+","+end.y+")"); 337 double theta = Math.atan((end.y - begin.y)/(end.x - begin.x)); 338 //System.out.println("Theta:"+theta); 339 end.y = Math.sin(theta)*length + begin.y; 340 end.x = Math.cos(theta)*length + begin.x; 341 //debugln("Pos-lengthen: ("+end.x+","+end.y+")"); 342 343 } 344 345 public void setDrawnAxisLength(int length){ 346 this.axisLength = length; 347 } 348 349 private void printPixelPoints(){ 350 debugln("center ("+centerP2d.x+","+centerP2d.y+")"); 351 debugln("x ("+xP2d.x+","+xP2d.y+")"); 352 debugln("y ("+yP2d.x+","+yP2d.y+")"); 353 debugln("z ("+zP2d.x+","+zP2d.y+")"); 354 } 355 356 private void printP3dPoints(){ 357 debugln("center P3D("+axisCenter.x+","+axisCenter.y+","+axisCenter.z+")"); 358 debugln("x P3D("+axisX.x+","+axisX.y+","+axisX.z+")"); 359 debugln("y P3D("+axisY.x+","+axisY.y+","+axisY.z+")"); 360 debugln("z P3D("+axisZ.x+","+axisZ.y+","+axisZ.z+")"); 361 } 362 363 void debugln(String s){ 364 if (GUIControl.debugflag){ 365 System.out.println(s); 366 } 367 } 368 369 void setOffScreenCanvas(OffScreenCanvas3D c) { 370 this.offCanvas = c; 371 } 372 373 public void setImageReady() { 374 imageReady = true; 375 } 376 377 378 379 }

This page was automatically generated by Maven