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