Visual Servoing Platform version 3.5.0
displayGDI.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2019 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 <iostream>
48
49#include <visp3/core/vpConfig.h>
50#include <visp3/core/vpDebug.h>
51
52#if (defined(_WIN32) && defined(VISP_HAVE_GDI))
53
54#include <visp3/gui/vpDisplayGDI.h>
55
56#include <visp3/core/vpImage.h>
57#include <visp3/core/vpIoTools.h>
58#include <visp3/io/vpImageIo.h>
59#include <visp3/io/vpParseArgv.h>
60
70// List of allowed command line options
71#define GETOPTARGS "cdi:o:h"
72
86void usage(const char *name, const char *badparam, std::string ipath, std::string opath, std::string user)
87{
88 fprintf(stdout, "\n\
89Read an image on the disk, display it using GDI, display some\n\
90features (line, circle, caracters) in overlay and finaly write \n\
91the image and the overlayed features in an image on the disk\n\
92\n\
93SYNOPSIS\n\
94 %s [-i <input image path>] [-o <output image path>]\n\
95 [-c] [-d] [-h]\n \
96", name);
97
98 fprintf(stdout, "\n\
99OPTIONS: Default\n\
100 -i <input image path> %s\n\
101 Set image input path.\n\
102 From this path read \"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 the task manager under \n\
121 Windows.\n\
122\n\
123 -h\n\
124 Print the help.\n\n", ipath.c_str(), opath.c_str(), user.c_str());
125
126 if (badparam)
127 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
128}
129
145bool getOptions(int argc, const char **argv, std::string &ipath, std::string &opath, bool &click_allowed,
146 const 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':
154 click_allowed = false;
155 break;
156 case 'd':
157 display = false;
158 break;
159 case 'i':
160 ipath = optarg;
161 break;
162 case 'o':
163 opath = optarg;
164 break;
165 case 'h':
166 usage(argv[0], NULL, ipath, opath, user);
167 return false;
168 break;
169
170 default:
171 usage(argv[0], optarg, ipath, opath, user);
172 return false;
173 break;
174 }
175 }
176
177 if ((c == 1) || (c == -1)) {
178 // standalone param or error
179 usage(argv[0], NULL, ipath, opath, user);
180 std::cerr << "ERROR: " << std::endl;
181 std::cerr << " Bad argument " << optarg << std::endl << std::endl;
182 return false;
183 }
184
185 return true;
186}
187
188int main(int argc, const char **argv)
189{
190 try {
191 std::string env_ipath;
192 std::string opt_ipath;
193 std::string opt_opath;
194 std::string ipath;
195 std::string opath;
196 std::string filename;
197 std::string username;
198 bool opt_click_allowed = true;
199 bool opt_display = true;
200
201 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
202 // environment variable value
204
205 // Set the default input path
206 if (!env_ipath.empty())
207 ipath = env_ipath;
208
209 // Set the default output path
210 opt_opath = "C:\\temp";
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, opt_click_allowed, username, opt_display) == false) {
217 exit(-1);
218 }
219
220 // Get the option values
221 if (!opt_ipath.empty())
222 ipath = opt_ipath;
223 if (!opt_opath.empty())
224 opath = opt_opath;
225
226 // Append to the output path string, the login name of the user
227 std::string odirname = vpIoTools::createFilePath(opath, username);
228
229 // Test if the output path exist. If no try to create it
230 if (vpIoTools::checkDirectory(odirname) == false) {
231 try {
232 // Create the dirname
233 vpIoTools::makeDirectory(odirname);
234 } catch (...) {
235 usage(argv[0], NULL, ipath, opath, username);
236 std::cerr << std::endl << "ERROR:" << std::endl;
237 std::cerr << " Cannot create " << odirname << std::endl;
238 std::cerr << " Check your -o " << opath << " option " << std::endl;
239 exit(-1);
240 }
241 }
242
243 // Compare ipath and env_ipath. If they differ, we take into account
244 // the input path comming from the command line option
245 if (!opt_ipath.empty() && !env_ipath.empty()) {
246 if (ipath != env_ipath) {
247 std::cout << std::endl << "WARNING: " << std::endl;
248 std::cout << " Since -i <visp image path=" << ipath << "> "
249 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
250 << " we skip the environment variable." << std::endl;
251 }
252 }
253
254 // Test if an input path is set
255 if (opt_ipath.empty() && env_ipath.empty()) {
256 usage(argv[0], NULL, ipath, opath, username);
257 std::cerr << std::endl << "ERROR:" << std::endl;
258 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
259 << " environment variable to specify the location of the " << std::endl
260 << " image path where test images are located." << std::endl
261 << 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, "Klimt/Klimt.pgm");
271 vpImageIo::read(I, filename);
272
273 // Create a display using X11
274 vpDisplayGDI 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
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());
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
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);
328
329 // Display in overlay some circles. The position of the center is 200,
330 // 200 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);
345 vpDisplay::displayText(I, ip, "ViSP is a marvelous software", vpColor::yellow);
346 // Flush the display
348
349 // Create a color image
350 vpImage<vpRGBa> Ioverlay;
351 // Updates the color image with the original loaded image and the
352 // overlay
353 vpDisplay::getImage(I, Ioverlay);
354
355 // Write the color image on the disk
356 filename = vpIoTools::createFilePath(odirname, "Klimt_grey.overlay.ppm");
357 vpImageIo::write(Ioverlay, filename);
358
359 // If click is allowed, wait for a mouse click to close the display
360 if (opt_click_allowed) {
361 std::cout << "\nA click to close the windows..." << std::endl;
362 // Wait for a blocking mouse click
364 }
365
366 // Close the display
368 }
369
370 // Create a color image
371 vpImage<vpRGBa> Irgba;
372
373 // Load a grey image from the disk and convert it to a color image
374 filename = vpIoTools::createFilePath(ipath, "Klimt/Klimt.ppm");
375 vpImageIo::read(Irgba, filename);
376
377 // Create a new display
378 vpDisplayGDI displayRGBa;
379
380 if (opt_display) {
381 // For this color image, open a X11 display at position 100,100
382 // in the screen, and with title "X11 color display"
383 displayRGBa.init(Irgba, 100, 100, "X11 color display");
384
385 // Display the color image
386 vpDisplay::display(Irgba);
387 vpDisplay::flush(Irgba);
388
389 // If click is allowed, wait for a blocking mouse click to display a
390 // cross at the clicked pixel position
391 if (opt_click_allowed) {
392 std::cout << "\nA click to display a cross..." << std::endl;
393 // Blocking wait for a click. Get the position of the selected pixel
394 // (i correspond to the row and j to the column coordinates in the
395 // image)
396 vpDisplay::getClick(Irgba, ip);
397 // Display a red cross on the click pixel position
398 std::cout << "Cross position: " << ip << std::endl;
400 } else {
401 ip.set_i(10);
402 ip.set_j(20);
403 // Display a red cross at position i, j (i correspond to the row
404 // and j to the column coordinates in the image)
405 std::cout << "Cross position: " << ip << std::endl;
407 }
408 // Flush the display. Sometimes the display content is
409 // bufferized. Force to display the content that has been bufferized.
410 vpDisplay::flush(Irgba);
411
412 // Create a color image
413 vpImage<vpRGBa> Ioverlay;
414 // Updates the color image with the original loaded image and the
415 // overlay
416 vpDisplay::getImage(Irgba, Ioverlay);
417
418 // Write the color image on the disk
419 filename = vpIoTools::createFilePath(odirname, "Klimt_color.overlay.ppm");
420 vpImageIo::write(Ioverlay, filename);
421
422 // If click is allowed, wait for a blocking mouse click to exit.
423 if (opt_click_allowed) {
424 std::cout << "\nA click to exit the program..." << std::endl;
425 vpDisplay::getClick(Irgba);
426 std::cout << "Bye" << std::endl;
427 }
428 }
429 return EXIT_SUCCESS;
430 } catch (const vpException &e) {
431 std::cout << "Catch an exception: " << e << std::endl;
432 return EXIT_FAILURE;
433 }
434}
435#else
436int main()
437{
438 std::cout << "You do not have GDI (Graphical Device Interface) functionalities to display images..." << std::endl;
439 std::cout << "Tip if you are on a windows system:" << std::endl;
440 std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
441 return EXIT_SUCCESS;
442}
443#endif
static const vpColor red
Definition: vpColor.h:217
static const vpColor orange
Definition: vpColor.h:227
static const vpColor blue
Definition: vpColor.h:223
static const vpColor yellow
Definition: vpColor.h:225
static const vpColor green
Definition: vpColor.h:220
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:129
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
static void close(vpImage< unsigned char > &I)
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
static void getImage(const vpImage< unsigned char > &Is, vpImage< vpRGBa > &Id)
Definition: vpDisplay.cpp:144
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void flush(const vpImage< unsigned char > &I)
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 displayDotLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
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 displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
static void displayCircle(const vpImage< unsigned char > &I, const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
error that can be emited by ViSP classes.
Definition: vpException.h:72
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:149
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:293
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
void set_j(double jj)
Definition: vpImagePoint.h:177
void set_i(double ii)
Definition: vpImagePoint.h:166
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getHeight() const
Definition: vpImage.h:188
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1365
static bool checkDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:420
static std::string getUserName()
Definition: vpIoTools.cpp:316
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1670
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:570
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69