ViSP
displayGDI.cpp
1 /****************************************************************************
2  *
3  * $Id: displayGDI.cpp 5004 2014-11-24 08:24:18Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 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  * Windows' GDI Display Test
36  *
37  * Authors:
38  * Bruno Renier
39  *
40  *****************************************************************************/
50 #include <visp/vpDebug.h>
51 #include <visp/vpConfig.h>
52 
53 #if ( defined(_WIN32) && defined(VISP_HAVE_GDI) )
54 
55 #include <visp/vpDisplayGDI.h>
56 
57 #include <visp/vpImage.h>
58 #include <visp/vpImageIo.h>
59 #include <visp/vpParseArgv.h>
60 #include <visp/vpIoTools.h>
61 
71 // List of allowed command line options
72 #define GETOPTARGS "cdi:o:h"
73 
87 void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
88 {
89  fprintf(stdout, "\n\
90 Read an image on the disk, display it using GDI, display some\n\
91 features (line, circle, caracters) in overlay and finaly write \n\
92 the image and the overlayed features in an image on the disk\n\
93 \n\
94 SYNOPSIS\n\
95  %s [-i <input image path>] [-o <output image path>]\n\
96  [-c] [-d] [-h]\n \
97 ", name);
98 
99  fprintf(stdout, "\n\
100 OPTIONS: Default\n\
101  -i <input image path> %s\n\
102  Set image input path.\n\
103  From this path read \"ViSP-images/Klimt/Klimt.pgm\"\n\
104  image.\n\
105  Setting the VISP_INPUT_IMAGE_PATH environment\n\
106  variable produces the same behaviour than using\n\
107  this option.\n\
108 \n\
109  -o <output image path> %s\n\
110  Set image output path.\n\
111  From this directory, creates the \"%s\"\n\
112  subdirectory depending on the username, where \n\
113  Klimt_grey.overlay.ppm output image is written.\n\
114 \n\
115  -c\n\
116  Disable the mouse click. Useful to automate the \n\
117  execution of this program without humain intervention.\n\
118 \n\
119  -d \n\
120  Disable the image display. This can be useful \n\
121  for automatic tests using the task manager under \n\
122  Windows.\n\
123 \n\
124  -h\n\
125  Print the help.\n\n",
126  ipath.c_str(), opath.c_str(), user.c_str());
127 
128  if (badparam)
129  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
130 
131 }
132 
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  opt_opath = "C:\\temp";
202 
203  // Get the user login name
204  vpIoTools::getUserName(username);
205 
206  // Read the command line options
207  if (getOptions(argc, argv, opt_ipath, opt_opath,
208  opt_click_allowed, username, opt_display) == false) {
209  exit (-1);
210  }
211 
212  // Get the option values
213  if (!opt_ipath.empty())
214  ipath = opt_ipath;
215  if (!opt_opath.empty())
216  opath = opt_opath;
217 
218  // Append to the output path string, the login name of the user
219  std::string odirname = vpIoTools::createFilePath(opath, username);
220 
221  // Test if the output path exist. If no try to create it
222  if (vpIoTools::checkDirectory(odirname) == false) {
223  try {
224  // Create the dirname
225  vpIoTools::makeDirectory(odirname);
226  }
227  catch (...) {
228  usage(argv[0], NULL, ipath, opath, username);
229  std::cerr << std::endl
230  << "ERROR:" << std::endl;
231  std::cerr << " Cannot create " << odirname << std::endl;
232  std::cerr << " Check your -o " << opath << " option " << std::endl;
233  exit(-1);
234  }
235  }
236 
237  // Compare ipath and env_ipath. If they differ, we take into account
238  // the input path comming from the command line option
239  if (!opt_ipath.empty() && !env_ipath.empty()) {
240  if (ipath != env_ipath) {
241  std::cout << std::endl
242  << "WARNING: " << std::endl;
243  std::cout << " Since -i <visp image path=" << ipath << "> "
244  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
245  << " we skip the environment variable." << std::endl;
246  }
247  }
248 
249  // Test if an input path is set
250  if (opt_ipath.empty() && env_ipath.empty()){
251  usage(argv[0], NULL, ipath, opath, username);
252  std::cerr << std::endl
253  << "ERROR:" << std::endl;
254  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
255  << std::endl
256  << " environment variable to specify the location of the " << std::endl
257  << " image path where test images are located." << std::endl << std::endl;
258  exit(-1);
259  }
260 
261  // Create a grey level image
263  vpImagePoint ip, ip1, ip2;
264 
265  // Load a grey image from the disk
266  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.pgm");
267  vpImageIo::read(I, filename) ;
268 
269  // Create a display using X11
270  vpDisplayGDI display;
271 
272  if (opt_display) {
273  // For this grey level image, open a X11 display at position 100,100
274  // in the screen, and with title "X11 display"
275  display.init(I, 100, 100, "X11 display") ;
276 
277  // Display the image
278  vpDisplay::display(I) ;
279 
280  // Display in overlay a red cross at position 10,10 in the
281  // image. The lines are 10 pixels long
282  ip.set_i( 100 );
283  ip.set_j( 10 );
284 
286 
287  // Display in overlay horizontal red lines
288  for (unsigned i=0 ; i < I.getHeight() ; i+=20) {
289  ip1.set_i( i );
290  ip1.set_j( 0 );
291  ip2.set_i( i );
292  ip2.set_j( I.getWidth() );
293  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
294  }
295 
296  // Display a ligne in the diagonal
297  ip1.set_i( -10 );
298  ip1.set_j( -10 );
299  ip2.set_i( I.getHeight() + 10 );
300  ip2.set_j( I.getWidth() + 10 );
301 
302  vpDisplay::displayLine(I, ip1, ip2, vpColor::red) ;
303 
304  // Display in overlay vertical green dot lines
305  for (unsigned i=0 ; i < I.getWidth() ; i+=20) {
306  ip1.set_i( 0 );
307  ip1.set_j( i );
308  ip2.set_i( I.getWidth() );
309  ip2.set_j( i );
311  }
312 
313  // Display a rectangle
314  ip.set_i( I.getHeight() - 45 );
315  ip.set_j( -10 );
317 
318  // Display in overlay a blue arrow
319  ip1.set_i( 0 );
320  ip1.set_j( 0 );
321  ip2.set_i( 100 );
322  ip2.set_j( 100 );
323  vpDisplay::displayArrow(I, ip1, ip2, vpColor::blue) ;
324 
325  // Display in overlay some circles. The position of the center is 200, 200
326  // the radius is increased by 20 pixels for each circle
327 
328  for (unsigned int i=0 ; i < 100 ; i+=20) {
329  ip.set_i( 80 );
330  ip.set_j( 80 );
332  }
333 
334  ip.set_i( -10 );
335  ip.set_j( 300 );
337 
338  // Display in overlay a yellow string
339  ip.set_i( 85 );
340  ip.set_j( 100 );
342  "ViSP is a marvelous software",
343  vpColor::yellow) ;
344  //Flush the display
345  vpDisplay::flush(I);
346 
347  // Create a color image
348  vpImage<vpRGBa> Ioverlay ;
349  // Updates the color image with the original loaded image and the overlay
350  vpDisplay::getImage(I, Ioverlay) ;
351 
352  // Write the color image on the disk
353  filename = vpIoTools::createFilePath(odirname, "Klimt_grey.overlay.ppm");
354  vpImageIo::write(Ioverlay, filename) ;
355 
356  // If click is allowed, wait for a mouse click to close the display
357  if (opt_click_allowed) {
358  std::cout << "\nA click to close the windows..." << std::endl;
359  // Wait for a blocking mouse click
361  }
362 
363  // Close the display
364  vpDisplay::close(I);
365  }
366 
367  // Create a color image
368  vpImage<vpRGBa> Irgba ;
369 
370  // Load a grey image from the disk and convert it to a color image
371  filename = vpIoTools::createFilePath(ipath, "ViSP-images/Klimt/Klimt.ppm");
372  vpImageIo::read(Irgba, filename) ;
373 
374  // Create a new display
375  vpDisplayGDI displayRGBa;
376 
377  if (opt_display) {
378  // For this color image, open a X11 display at position 100,100
379  // in the screen, and with title "X11 color display"
380  displayRGBa.init(Irgba, 100, 100, "X11 color display");
381 
382  // Display the color image
383  vpDisplay::display(Irgba) ;
384  vpDisplay::flush(Irgba) ;
385 
386  // If click is allowed, wait for a blocking mouse click to display a cross
387  // at the clicked pixel position
388  if (opt_click_allowed) {
389  std::cout << "\nA click to display a cross..." << std::endl;
390  // Blocking wait for a click. Get the position of the selected pixel
391  // (i correspond to the row and j to the column coordinates in the image)
392  vpDisplay::getClick(Irgba, ip);
393  // Display a red cross on the click pixel position
394  std::cout << "Cross position: " << ip << std::endl;
395  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
396  }
397  else {
398  ip.set_i( 10 );
399  ip.set_j( 20 );
400  // Display a red cross at position i, j (i correspond to the row
401  // and j to the column coordinates in the image)
402  std::cout << "Cross position: " << ip << std::endl;
403  vpDisplay::displayCross(Irgba, ip, 15, vpColor::red);
404 
405  }
406  // Flush the display. Sometimes the display content is
407  // bufferized. Force to display the content that has been bufferized.
408  vpDisplay::flush(Irgba);
409 
410  // Create a color image
411  vpImage<vpRGBa> Ioverlay ;
412  // Updates the color image with the original loaded image and the overlay
413  vpDisplay::getImage(Irgba, Ioverlay) ;
414 
415  // Write the color image on the disk
416  filename = vpIoTools::createFilePath(odirname, "Klimt_color.overlay.ppm");
417  vpImageIo::write(Ioverlay, filename) ;
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  return 0;
427  }
428  catch(vpException e) {
429  std::cout << "Catch an exception: " << e << std::endl;
430  return 1;
431  }
432 }
433 #else
434 int
435 main()
436 {
437  vpERROR_TRACE("GDI display only works under windows...");
438 }
439 #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:476
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:315
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1071
static void close(vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:2269
unsigned int getWidth() const
Definition: vpImage.h:161
#define vpERROR_TRACE
Definition: vpDebug.h:395
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:132
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Definition: vpDisplay.cpp:887
error that can be emited by ViSP classes.
Definition: vpException.h:76
static const vpColor green
Definition: vpColor.h:170
static void flush(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:2232
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:80
static const vpColor red
Definition: vpColor.h:167
static const vpColor orange
Definition: vpColor.h:177
static void makeDirectory(const char *dirname)
Definition: vpIoTools.cpp:384
void set_i(const double ii)
Definition: vpImagePoint.h:159
static std::string createFilePath(const std::string &parent, const std::string child)
Definition: vpIoTools.cpp:1245
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:210
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
static std::string getUserName()
Definition: vpIoTools.cpp:141
virtual void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)=0
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
static void getImage(const vpImage< unsigned char > &Is, vpImage< vpRGBa > &Id)
Definition: vpDisplay.cpp:328
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:170
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:93
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:278
static const vpColor yellow
Definition: vpColor.h:175
static const vpColor blue
Definition: vpColor.h:173