Visual Servoing Platform  version 3.0.1
displayGDI.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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  * Windows' GDI Display Test
32  *
33  * Authors:
34  * Bruno Renier
35  *
36  *****************************************************************************/
46 #include <visp3/core/vpDebug.h>
47 #include <visp3/core/vpConfig.h>
48 
49 #if ( defined(_WIN32) && defined(VISP_HAVE_GDI) )
50 
51 #include <visp3/gui/vpDisplayGDI.h>
52 
53 #include <visp3/core/vpImage.h>
54 #include <visp3/io/vpImageIo.h>
55 #include <visp3/io/vpParseArgv.h>
56 #include <visp3/core/vpIoTools.h>
57 
67 // List of allowed command line options
68 #define GETOPTARGS "cdi:o:h"
69 
83 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
84 {
85  fprintf(stdout, "\n\
86 Read an image on the disk, display it using GDI, display some\n\
87 features (line, circle, caracters) in overlay and finaly write \n\
88 the image and the overlayed features in an image on the disk\n\
89 \n\
90 SYNOPSIS\n\
91  %s [-i <input image path>] [-o <output image path>]\n\
92  [-c] [-d] [-h]\n \
93 ", name);
94 
95  fprintf(stdout, "\n\
96 OPTIONS: Default\n\
97  -i <input image path> %s\n\
98  Set image input path.\n\
99  From this path read \"ViSP-images/Klimt/Klimt.pgm\"\n\
100  image.\n\
101  Setting the VISP_INPUT_IMAGE_PATH environment\n\
102  variable produces the same behaviour than using\n\
103  this option.\n\
104 \n\
105  -o <output image path> %s\n\
106  Set image output path.\n\
107  From this directory, creates the \"%s\"\n\
108  subdirectory depending on the username, where \n\
109  Klimt_grey.overlay.ppm output image is written.\n\
110 \n\
111  -c\n\
112  Disable the mouse click. Useful to automate the \n\
113  execution of this program without humain intervention.\n\
114 \n\
115  -d \n\
116  Disable the image display. This can be useful \n\
117  for automatic tests using the task manager under \n\
118  Windows.\n\
119 \n\
120  -h\n\
121  Print the help.\n\n",
122  ipath.c_str(), opath.c_str(), user.c_str());
123 
124  if (badparam)
125  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
126 
127 }
128 
144 bool getOptions(int argc, const char **argv,
145  std::string &ipath, std::string &opath, bool &click_allowed,
146  std::string user, bool &display)
147 {
148  const char *optarg;
149  int c;
150  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg)) > 1) {
151 
152  switch (c) {
153  case 'c': click_allowed = false; break;
154  case 'd': display = false; break;
155  case 'i': ipath = optarg; break;
156  case 'o': opath = optarg; break;
157  case 'h': usage(argv[0], NULL, ipath, opath, user); return false; break;
158 
159  default:
160  usage(argv[0], optarg, ipath, opath, user); return false; break;
161  }
162  }
163 
164  if ((c == 1) || (c == -1)) {
165  // standalone param or error
166  usage(argv[0], NULL, ipath, opath, user);
167  std::cerr << "ERROR: " << std::endl;
168  std::cerr << " Bad argument " << optarg << std::endl << std::endl;
169  return false;
170  }
171 
172  return true;
173 }
174 
175 int
176 main(int argc, const char ** argv)
177 {
178  try {
179  std::string env_ipath;
180  std::string opt_ipath;
181  std::string opt_opath;
182  std::string ipath;
183  std::string opath;
184  std::string filename;
185  std::string username;
186  bool opt_click_allowed = true;
187  bool opt_display = true;
188 
189  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
190  env_ipath = vpIoTools::getViSPImagesDataPath();
191 
192  // Set the default input path
193  if (! env_ipath.empty())
194  ipath = env_ipath;
195 
196  // Set the default output path
197  opt_opath = "C:\\temp";
198 
199  // Get the user login name
200  vpIoTools::getUserName(username);
201 
202  // Read the command line options
203  if (getOptions(argc, argv, opt_ipath, opt_opath,
204  opt_click_allowed, username, opt_display) == false) {
205  exit (-1);
206  }
207 
208  // Get the option values
209  if (!opt_ipath.empty())
210  ipath = opt_ipath;
211  if (!opt_opath.empty())
212  opath = opt_opath;
213 
214  // Append to the output path string, the login name of the user
215  std::string odirname = vpIoTools::createFilePath(opath, username);
216 
217  // Test if the output path exist. If no try to create it
218  if (vpIoTools::checkDirectory(odirname) == false) {
219  try {
220  // Create the dirname
221  vpIoTools::makeDirectory(odirname);
222  }
223  catch (...) {
224  usage(argv[0], NULL, ipath, opath, username);
225  std::cerr << std::endl
226  << "ERROR:" << std::endl;
227  std::cerr << " Cannot create " << odirname << std::endl;
228  std::cerr << " Check your -o " << opath << " option " << std::endl;
229  exit(-1);
230  }
231  }
232 
233  // Compare ipath and env_ipath. If they differ, we take into account
234  // the input path comming from the command line option
235  if (!opt_ipath.empty() && !env_ipath.empty()) {
236  if (ipath != env_ipath) {
237  std::cout << std::endl
238  << "WARNING: " << std::endl;
239  std::cout << " Since -i <visp image path=" << ipath << "> "
240  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
241  << " we skip the environment variable." << std::endl;
242  }
243  }
244 
245  // Test if an input path is set
246  if (opt_ipath.empty() && env_ipath.empty()){
247  usage(argv[0], NULL, ipath, opath, username);
248  std::cerr << std::endl
249  << "ERROR:" << std::endl;
250  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
251  << std::endl
252  << " environment variable to specify the location of the " << std::endl
253  << " image path where test images are located." << std::endl << std::endl;
254  exit(-1);
255  }
256 
257  // Create a grey level image
259  vpImagePoint ip, ip1, ip2;
260 
261  // Load a grey image from the disk
262  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
263  vpImageIo::read(I, filename) ;
264 
265  // Create a display using X11
266  vpDisplayGDI display;
267 
268  if (opt_display) {
269  // For this grey level image, open a X11 display at position 100,100
270  // in the screen, and with title "X11 display"
271  display.init(I, 100, 100, "X11 display") ;
272 
273  // Display the image
274  vpDisplay::display(I) ;
275 
276  // Display in overlay a red cross at position 10,10 in the
277  // image. The lines are 10 pixels long
278  ip.set_i( 100 );
279  ip.set_j( 10 );
280 
282 
283  // Display in overlay horizontal red lines
284  for (unsigned i=0 ; i < I.getHeight() ; i+=20) {
285  ip1.set_i( i );
286  ip1.set_j( 0 );
287  ip2.set_i( i );
288  ip2.set_j( I.getWidth() );
289  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
290  }
291 
292  // Display a ligne in the diagonal
293  ip1.set_i( -10 );
294  ip1.set_j( -10 );
295  ip2.set_i( I.getHeight() + 10 );
296  ip2.set_j( I.getWidth() + 10 );
297 
298  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
299 
300  // Display in overlay vertical green dot lines
301  for (unsigned i=0 ; i < I.getWidth() ; i+=20) {
302  ip1.set_i( 0 );
303  ip1.set_j( i );
304  ip2.set_i( I.getWidth() );
305  ip2.set_j( i );
307  }
308 
309  // Display a rectangle
310  ip.set_i( I.getHeight() - 45 );
311  ip.set_j( -10 );
313 
314  // Display in overlay a blue arrow
315  ip1.set_i( 0 );
316  ip1.set_j( 0 );
317  ip2.set_i( 100 );
318  ip2.set_j( 100 );
319  vpDisplay::displayArrow(I, ip1, ip2, vpColor::blue) ;
320 
321  // Display in overlay some circles. The position of the center is 200, 200
322  // the radius is increased by 20 pixels for each circle
323 
324  for (unsigned int i=0 ; i < 100 ; i+=20) {
325  ip.set_i( 80 );
326  ip.set_j( 80 );
328  }
329 
330  ip.set_i( -10 );
331  ip.set_j( 300 );
333 
334  // Display in overlay a yellow string
335  ip.set_i( 85 );
336  ip.set_j( 100 );
338  "ViSP is a marvelous software",
339  vpColor::yellow) ;
340  //Flush the display
341  vpDisplay::flush(I);
342 
343  // Create a color image
344  vpImage<vpRGBa> Ioverlay ;
345  // Updates the color image with the original loaded image and the overlay
346  vpDisplay::getImage(I, Ioverlay) ;
347 
348  // Write the color image on the disk
349  filename = vpIoTools::createFilePath(odirname, "Klimt_grey.overlay.ppm");
350  vpImageIo::write(Ioverlay, filename) ;
351 
352  // If click is allowed, wait for a mouse click to close the display
353  if (opt_click_allowed) {
354  std::cout << "\nA click to close the windows..." << std::endl;
355  // Wait for a blocking mouse click
357  }
358 
359  // Close the display
360  vpDisplay::close(I);
361  }
362 
363  // Create a color image
364  vpImage<vpRGBa> Irgba ;
365 
366  // Load a grey image from the disk and convert it to a color image
367  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
368  vpImageIo::read(Irgba, filename) ;
369 
370  // Create a new display
371  vpDisplayGDI displayRGBa;
372 
373  if (opt_display) {
374  // For this color image, open a X11 display at position 100,100
375  // in the screen, and with title "X11 color display"
376  displayRGBa.init(Irgba, 100, 100, "X11 color display");
377 
378  // Display the color image
379  vpDisplay::display(Irgba) ;
380  vpDisplay::flush(Irgba) ;
381 
382  // If click is allowed, wait for a blocking mouse click to display a cross
383  // at the clicked pixel position
384  if (opt_click_allowed) {
385  std::cout << "\nA click to display a cross..." << std::endl;
386  // Blocking wait for a click. Get the position of the selected pixel
387  // (i correspond to the row and j to the column coordinates in the image)
388  vpDisplay::getClick(Irgba, ip);
389  // Display a red cross on the click pixel position
390  std::cout << "Cross position: " << ip << std::endl;
391  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
392  }
393  else {
394  ip.set_i( 10 );
395  ip.set_j( 20 );
396  // Display a red cross at position i, j (i correspond to the row
397  // and j to the column coordinates in the image)
398  std::cout << "Cross position: " << ip << std::endl;
399  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
400 
401  }
402  // Flush the display. Sometimes the display content is
403  // bufferized. Force to display the content that has been bufferized.
404  vpDisplay::flush(Irgba);
405 
406  // Create a color image
407  vpImage<vpRGBa> Ioverlay ;
408  // Updates the color image with the original loaded image and the overlay
409  vpDisplay::getImage(Irgba, Ioverlay) ;
410 
411  // Write the color image on the disk
412  filename = vpIoTools::createFilePath(odirname, "Klimt_color.overlay.ppm");
413  vpImageIo::write(Ioverlay, filename) ;
414 
415  // If click is allowed, wait for a blocking mouse click to exit.
416  if (opt_click_allowed) {
417  std::cout << "\nA click to exit the program..." << std::endl;
418  vpDisplay::getClick(Irgba) ;
419  std::cout << "Bye" << std::endl;
420  }
421  }
422  return 0;
423  }
424  catch(vpException &e) {
425  std::cout << "Catch an exception: " << e << std::endl;
426  return 1;
427  }
428 }
429 #else
430 int
431 main()
432 {
433  vpERROR_TRACE("GDI display only works under windows...");
434 }
435 #endif
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static bool checkDirectory(const char *dirname)
Definition: vpIoTools.cpp:358
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1157
static void close(vpImage< unsigned char > &I)
#define vpERROR_TRACE
Definition: vpDebug.h:391
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emited by ViSP classes.
Definition: vpException.h:73
static const vpColor green
Definition: vpColor.h:166
static void flush(const vpImage< unsigned char > &I)
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 write(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:368
static void makeDirectory(const char *dirname)
Definition: vpIoTools.cpp:427
void set_i(const double ii)
Definition: vpImagePoint.h:163
static void displayArrow(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)
static std::string createFilePath(const std::string &parent, const std::string child)
Definition: vpIoTools.cpp:1366
static void display(const vpImage< unsigned char > &I)
static std::string getUserName()
Definition: vpIoTools.cpp:177
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void getImage(const vpImage< unsigned char > &Is, vpImage< vpRGBa > &Id)
Definition: vpDisplay.cpp:155
void set_j(const double jj)
Definition: vpImagePoint.h:174
static void displayCircle(const vpImage< unsigned char > &I, const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
unsigned int getHeight() const
Definition: vpImage.h:175
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:205
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
static const vpColor yellow
Definition: vpColor.h:171
unsigned int getWidth() const
Definition: vpImage.h:226
static void displayDotLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
static const vpColor blue
Definition: vpColor.h:169