ViSP
 All Classes Functions Variables Enumerations Enumerator Friends Groups Pages
displayGTK.cpp
1 /****************************************************************************
2  *
3  * $Id: displayGTK.cpp 4056 2013-01-05 13:04:42Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Read an image on the disk and display it using GTK.
36  *
37  * Authors:
38  * Eric Marchand
39  * Fabien Spindler
40  *
41  *****************************************************************************/
52 #include <visp/vpDebug.h>
53 #include <visp/vpConfig.h>
54 
55 #ifdef VISP_HAVE_GTK
56 
57 #include <stdlib.h>
58 #include <stdio.h>
59 
60 #include <visp/vpImage.h>
61 #include <visp/vpImageIo.h>
62 #include <visp/vpImagePoint.h>
63 #include <visp/vpDisplayGTK.h>
64 #include <visp/vpParseArgv.h>
65 #include <visp/vpIoTools.h>
66 
76 // List of allowed command line options
77 #define GETOPTARGS "cdi:o:h"
78 
90 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
91 {
92  fprintf(stdout, "\n\
93 Read an image on the disk, display it using GTK, display some\n\
94 features (line, circle, caracters) in overlay and finaly write \n\
95 the image and the overlayed features in an image on the disk\n\
96 \n\
97 SYNOPSIS\n\
98  %s [-i <input image path>] [-o <output image path>]\n\
99  [-c] [-d] [-h]\n \
100 ", name);
101 
102  fprintf(stdout, "\n\
103 OPTIONS: Default\n\
104  -i <input image path> %s\n\
105  Set image input path.\n\
106  From this path read \"ViSP-images/Klimt/Klimt.pgm\"\n\
107  image.\n\
108  Setting the VISP_INPUT_IMAGE_PATH environment\n\
109  variable produces the same behaviour than using\n\
110  this option.\n\
111 \n\
112  -o <output image path> %s\n\
113  Set image output path.\n\
114  From this directory, creates the \"%s\"\n\
115  subdirectory depending on the username, where \n\
116  Klimt_grey.overlay.ppm output image is written.\n\
117 \n\
118  -c\n\
119  Disable the mouse click. Useful to automate the \n\
120  execution of this program without humain intervention.\n\
121 \n\
122  -d \n\
123  Disable the image display. This can be useful \n\
124  for automatic tests using crontab under Unix or \n\
125  using the task manager under Windows.\n\
126 \n\
127  -h\n\
128  Print the help.\n\n",
129  ipath.c_str(), opath.c_str(), user.c_str());
130 
131  if (badparam)
132  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
133 }
134 
152 bool getOptions(int argc, const char **argv,
153  std::string &ipath, std::string &opath, bool &click_allowed,
154  std::string user, bool &display)
155 {
156  const char *optarg;
157  int c;
158  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg)) > 1) {
159 
160  switch (c) {
161  case 'c': click_allowed = false; break;
162  case 'd': display = false; break;
163  case 'i': ipath = optarg; break;
164  case 'o': opath = optarg; break;
165  case 'h': usage(argv[0], NULL, ipath, opath, user); return false; break;
166 
167  default:
168  usage(argv[0], optarg, ipath, opath, user); return false; break;
169  }
170  }
171 
172  if ((c == 1) || (c == -1)) {
173  // standalone param or error
174  usage(argv[0], NULL, ipath, opath, user);
175  std::cerr << "ERROR: " << std::endl;
176  std::cerr << " Bad argument " << optarg << std::endl << std::endl;
177  return false;
178  }
179 
180  return true;
181 }
182 
183 int
184 main(int argc, const char ** argv)
185 {
186  std::string env_ipath;
187  std::string opt_ipath;
188  std::string opt_opath;
189  std::string ipath;
190  std::string opath;
191  std::string filename;
192  std::string username;
193  bool opt_click_allowed = true;
194  bool opt_display = true;
195 
196  // Get the VISP_IMAGE_PATH environment variable value
197  char *ptenv = getenv("VISP_INPUT_IMAGE_PATH");
198  if (ptenv != NULL)
199  env_ipath = ptenv;
200 
201  // Set the default input path
202  if (! env_ipath.empty())
203  ipath = env_ipath;
204 
205  // Set the default output path
206 #ifdef UNIX
207  opt_opath = "/tmp";
208 #elif WIN32
209  opt_opath = "C:\\temp";
210 #endif
211 
212  // Get the user login name
213  vpIoTools::getUserName(username);
214 
215  // Read the command line options
216  if (getOptions(argc, argv, opt_ipath, opt_opath,
217  opt_click_allowed, username, opt_display) == false) {
218  exit (-1);
219  }
220 
221  // Get the option values
222  if (!opt_ipath.empty())
223  ipath = opt_ipath;
224  if (!opt_opath.empty())
225  opath = opt_opath;
226 
227  // Append to the output path string, the login name of the user
228  std::string odirname = opath + vpIoTools::path("/") + username;
229 
230  // Test if the output path exist. If no try to create it
231  if (vpIoTools::checkDirectory(odirname) == false) {
232  try {
233  // Create the dirname
234  vpIoTools::makeDirectory(odirname);
235  }
236  catch (...) {
237  usage(argv[0], NULL, ipath, opath, username);
238  std::cerr << std::endl
239  << "ERROR:" << std::endl;
240  std::cerr << " Cannot create " << odirname << std::endl;
241  std::cerr << " Check your -o " << opath << " option " << std::endl;
242  exit(-1);
243  }
244  }
245 
246  // Compare ipath and env_ipath. If they differ, we take into account
247  // the input path comming from the command line option
248  if (!opt_ipath.empty() && !env_ipath.empty()) {
249  if (ipath != env_ipath) {
250  std::cout << std::endl
251  << "WARNING: " << std::endl;
252  std::cout << " Since -i <visp image path=" << ipath << "> "
253  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
254  << " we skip the environment variable." << std::endl;
255  }
256  }
257 
258  // Test if an input path is set
259  if (opt_ipath.empty() && env_ipath.empty()){
260  usage(argv[0], NULL, ipath, opath, username);
261  std::cerr << std::endl
262  << "ERROR:" << std::endl;
263  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
264  << std::endl
265  << " environment variable to specify the location of the " << std::endl
266  << " image path where test images are located." << std::endl << std::endl;
267  exit(-1);
268  }
269 
270  // Create a grey level image
272  vpImagePoint ip, ip1, ip2;
273 
274  // Load a grey image from the disk
275  filename = ipath + vpIoTools::path("/ViSP-images/Klimt/Klimt.png");
276  vpImageIo::read(I, filename) ;
277 
278  // Create a display using GTK
279  vpDisplayGTK display;
280 
281  if (opt_display) {
282  // For this grey level image, open a GTK display at position 100,100
283  // in the screen, and with title "GTK display"
284  display.init(I, 100, 100, "GTK display") ;
285 
286  // Display the image
287  vpDisplay::display(I) ;
288 
289  // Display in overlay a red cross at position 10,10 in the
290  // image. The lines are 10 pixels long
291  ip.set_i( 100 );
292  ip.set_j( 10 );
293 
295 
296  // Display in overlay horizontal red lines
297  for (unsigned i=0 ; i < I.getHeight() ; i+=20) {
298  ip1.set_i( i );
299  ip1.set_j( 0 );
300  ip2.set_i( i );
301  ip2.set_j( I.getWidth() );
302  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
303  }
304 
305  // Display a ligne in the diagonal
306  ip1.set_i( -10 );
307  ip1.set_j( -10 );
308  ip2.set_i( I.getHeight() + 10 );
309  ip2.set_j( I.getWidth() + 10 );
310 
311  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
312 
313  // Display in overlay vertical green dot lines
314  for (unsigned i=0 ; i < I.getWidth() ; i+=20) {
315  ip1.set_i( 0 );
316  ip1.set_j( i );
317  ip2.set_i( I.getWidth() );
318  ip2.set_j( i );
320  }
321 
322  // Display a rectangle
323  ip.set_i( I.getHeight() - 45 );
324  ip.set_j( -10 );
326 
327  // Display in overlay a blue arrow
328  ip1.set_i( 0 );
329  ip1.set_j( 0 );
330  ip2.set_i( 100 );
331  ip2.set_j( 100 );
332  vpDisplay::displayArrow(I, ip1, ip2, vpColor::blue) ;
333 
334  // Display in overlay some circles. The position of the center is 200, 200
335  // the radius is increased by 20 pixels for each circle
336 
337  for (unsigned int i=0 ; i < 100 ; i+=20) {
338  ip.set_i( 80 );
339  ip.set_j( 80 );
341  }
342 
343  ip.set_i( -10 );
344  ip.set_j( 300 );
346 
347  // Display in overlay a yellow string
348  ip.set_i( 85 );
349  ip.set_j( 100 );
351  "ViSP is a marvelous software",
352  vpColor::yellow) ;
353  //Flush the display
354  vpDisplay::flush(I);
355 
356  // Create a color image
357  vpImage<vpRGBa> Ioverlay ;
358  // Updates the color image with the original loaded image and the overlay
359  vpDisplay::getImage(I, Ioverlay) ;
360 
361  // Write the color image on the disk
362  filename = odirname + vpIoTools::path("/Klimt_grey.overlay.ppm");
363  vpImageIo::write(Ioverlay, filename) ;
364 
365  // If click is allowed, wait for a mouse click to close the display
366  if (opt_click_allowed) {
367  std::cout << "\nA click to close the windows..." << std::endl;
368  // Wait for a blocking mouse click
370  }
371 
372  // Close the display
373  vpDisplay::close(I);
374  }
375 
376  // Create a color image
377  vpImage<vpRGBa> Irgba ;
378 
379  // Load a grey image from the disk and convert it to a color image
380  filename = ipath + vpIoTools::path("/ViSP-images/Klimt/Klimt.pgm");
381  vpImageIo::read(Irgba, filename) ;
382 
383  // Create a new GTK display
384  vpDisplayGTK displayRGBa;
385 
386  if (opt_display) {
387  // For this color image, open a GTK display at position 100,100
388  // in the screen, and with title "GTK color display"
389  displayRGBa.init(Irgba, 100, 100, "GTK color display");
390 
391  // Display the color image
392  vpDisplay::display(Irgba) ;
393  vpDisplay::flush(Irgba) ;
394 
395  // If click is allowed, wait for a blocking mouse click to display a cross
396  // at the clicked pixel position
397  if (opt_click_allowed) {
398  std::cout << "\nA click to display a cross..." << std::endl;
399  // Blocking wait for a click. Get the position of the selected pixel
400  // (i correspond to the row and j to the column coordinates in the image)
401  vpDisplay::getClick(Irgba, ip);
402  // Display a red cross on the click pixel position
403  std::cout << "Cross position: " << ip << std::endl;
404  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
405  }
406  else {
407  ip.set_i( 10 );
408  ip.set_j( 20 );
409  // Display a red cross at position i, j (i correspond to the row
410  // and j to the column coordinates in the image)
411  std::cout << "Cross position: " << ip << std::endl;
412  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
413 
414  }
415  // Flush the display. Sometimes the display content is
416  // bufferized. Force to display the content that has been bufferized.
417  vpDisplay::flush(Irgba);
418 
419  // If click is allowed, wait for a blocking mouse click to exit.
420  if (opt_click_allowed) {
421  std::cout << "\nA click to exit the program..." << std::endl;
422  vpDisplay::getClick(Irgba) ;
423  std::cout << "Bye" << std::endl;
424  }
425  }
426 }
427 #else
428 int
429 main()
430 {
431  vpERROR_TRACE("You do not have GTK functionalities to display images...");
432 }
433 
434 #endif
435