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