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