Fri, 25 Sep 2009 10:50:44 +0100
added dots-per-inch to status readback
philpem@5 | 1 | /*------------------------------------------------------------------------ |
philpem@5 | 2 | # |
philpem@5 | 3 | # File : CImg_documentation.h |
philpem@5 | 4 | # |
philpem@5 | 5 | # Description : Extra documentation file for the CImg Library. |
philpem@5 | 6 | # Used by doxygen to generate the reference documentation. |
philpem@5 | 7 | # ( http://cimg.sourceforge.net ) |
philpem@5 | 8 | # |
philpem@5 | 9 | # Copyright : David Tschumperle |
philpem@5 | 10 | # ( http://www.greyc.ensicaen.fr/~dtschump/ ) |
philpem@5 | 11 | # |
philpem@5 | 12 | # |
philpem@5 | 13 | -------------------------------------------------------------------------*/ |
philpem@5 | 14 | |
philpem@5 | 15 | /*----------------------------------- |
philpem@5 | 16 | |
philpem@5 | 17 | Main reference documentation page |
philpem@5 | 18 | |
philpem@5 | 19 | -------------------------------------*/ |
philpem@5 | 20 | |
philpem@5 | 21 | /** |
philpem@5 | 22 | \mainpage |
philpem@5 | 23 | |
philpem@5 | 24 | This is the reference documentation of <a href="http://cimg.sourceforge.net">the CImg Library</a>, |
philpem@5 | 25 | the C++ template image processing library. |
philpem@5 | 26 | This documentation have been generated using the tool <a href="http://www.doxygen.org">doxygen</a>. |
philpem@5 | 27 | It contains a detailed description of all classes and functions of the %CImg Library. |
philpem@5 | 28 | If you have downloaded the CImg package, you actually have a local copy of these pages in the |
philpem@5 | 29 | \c CImg/html/reference/ directory. |
philpem@5 | 30 | |
philpem@5 | 31 | Use the menu above to navigate through the documentation pages. |
philpem@5 | 32 | As a first step, you may look at the list of <a href="modules.html">available modules</a>. |
philpem@5 | 33 | |
philpem@5 | 34 | A complete PDF version of this reference documentation is |
philpem@5 | 35 | <a href="../CImg_reference.pdf">available here</a> for off-line reading. |
philpem@5 | 36 | |
philpem@5 | 37 | A partial translation in Chinese is <a href="../CImg_reference_chinese.pdf">available here</a>. |
philpem@5 | 38 | |
philpem@5 | 39 | You may be interested also in the |
philpem@5 | 40 | <a href="../CImg_slides.pdf">presentation slides</a> presenting an overview |
philpem@5 | 41 | of the %CImg Library capabilities. |
philpem@5 | 42 | |
philpem@5 | 43 | **/ |
philpem@5 | 44 | |
philpem@5 | 45 | /*----------------------------------- |
philpem@5 | 46 | |
philpem@5 | 47 | CImg Library overview |
philpem@5 | 48 | |
philpem@5 | 49 | -------------------------------------*/ |
philpem@5 | 50 | |
philpem@5 | 51 | /** \addtogroup cimg_overview CImg Library Overview */ |
philpem@5 | 52 | /*@{*/ |
philpem@5 | 53 | /** |
philpem@5 | 54 | \page foo2 |
philpem@5 | 55 | |
philpem@5 | 56 | The <b>CImg Library</b> is an image processing library, designed for C++ programmers. |
philpem@5 | 57 | It provides useful classes and functions to load/save, display and process various types of images. |
philpem@5 | 58 | |
philpem@5 | 59 | \section s1 Library structure |
philpem@5 | 60 | |
philpem@5 | 61 | The %CImg Library consists in a <b>single header file</b> CImg.h providing a set of C++ template classes that |
philpem@5 | 62 | can be used in your own sources, to load/save, process and display images or list of images. |
philpem@5 | 63 | Very portable (Unix/X11,Windows, MacOS X, FreeBSD,..), efficient, simple to use, it's a pleasant toolkit |
philpem@5 | 64 | for coding image processing stuffs in C++. |
philpem@5 | 65 | |
philpem@5 | 66 | The header file CImg.h contains all the classes and functions that compose the library itself. |
philpem@5 | 67 | This is one originality of the %CImg Library. This particularly means that : |
philpem@5 | 68 | - No pre-compilation of the library is needed, since the compilation of the CImg functions is done at the same time as |
philpem@5 | 69 | the compilation of your own C++ code. |
philpem@5 | 70 | - No complex dependencies have to be handled : Just include the CImg.h file, and you get a working C++ image processing toolkit. |
philpem@5 | 71 | - The compilation is done on the fly : only CImg functionalities really used by your program are compiled and appear in the |
philpem@5 | 72 | compiled executable program. This leads to very compact code, without any unused stuffs. |
philpem@5 | 73 | - Class members and functions are inlined, leading to better performance during the program execution. |
philpem@5 | 74 | |
philpem@5 | 75 | The %CImg Library is structured as follows : |
philpem@5 | 76 | |
philpem@5 | 77 | - All library classes and functions are defined in the namespace \ref cimg_library. This namespace |
philpem@5 | 78 | encapsulates the library functionalities and avoid any class name collision that could happen with |
philpem@5 | 79 | other includes. Generally, one uses this namespace as a default namespace : |
philpem@5 | 80 | \code |
philpem@5 | 81 | #include "CImg.h" |
philpem@5 | 82 | using namespace cimg_library; |
philpem@5 | 83 | ... |
philpem@5 | 84 | \endcode |
philpem@5 | 85 | |
philpem@5 | 86 | - The namespace \ref cimg_library::cimg defines a set of \e low-level functions and variables used by the library. |
philpem@5 | 87 | Documented functions in this namespace can be safely used in your own program. But, \b never use the |
philpem@5 | 88 | \ref cimg_library::cimg namespace as a default namespace, since it contains functions whose names are already |
philpem@5 | 89 | defined in the standard C/C++ library. |
philpem@5 | 90 | |
philpem@5 | 91 | - The class \ref cimg_library::CImg<T> represents images up to 4-dimensions wide, containing pixels of type \c T |
philpem@5 | 92 | (template parameter). This is actually the main class of the library. |
philpem@5 | 93 | |
philpem@5 | 94 | - The class \ref cimg_library::CImgList<T> represents lists of cimg_library::CImg<T> images. It can be used for instance |
philpem@5 | 95 | to store different frames of an image sequence. |
philpem@5 | 96 | |
philpem@5 | 97 | - The class \ref cimg_library::CImgDisplay is able to display images or image lists into graphical display windows. |
philpem@5 | 98 | As you may guess, the code of this class is highly system-dependent but this is transparent for the programmer, |
philpem@5 | 99 | as environment variables are automatically set by the CImg library (see also \ref cimg_environment). |
philpem@5 | 100 | |
philpem@5 | 101 | - The class \ref cimg_library::CImgException (and its subclasses) are used by the library to throw exceptions |
philpem@5 | 102 | when errors occur. Those exceptions can be catched with a bloc <tt>try { ..} catch (CImgException) { .. }</tt>. |
philpem@5 | 103 | Subclasses define precisely the type of encountered errors. |
philpem@5 | 104 | |
philpem@5 | 105 | Knowing these four classes is \b enough to get benefit of the %CImg Library functionalities. |
philpem@5 | 106 | |
philpem@5 | 107 | |
philpem@5 | 108 | \section s2 CImg version of "Hello world". |
philpem@5 | 109 | |
philpem@5 | 110 | Below is a very simple code that creates a "Hello World" image. This shows you basically how a CImg program looks like. |
philpem@5 | 111 | |
philpem@5 | 112 | \code |
philpem@5 | 113 | #include "CImg.h" |
philpem@5 | 114 | using namespace cimg_library; |
philpem@5 | 115 | |
philpem@5 | 116 | int main() { |
philpem@5 | 117 | CImg<unsigned char> img(640,400,1,3); // Define a 640x400 color image with 8 bits per color component. |
philpem@5 | 118 | img.fill(0); // Set pixel values to 0 (color : black) |
philpem@5 | 119 | unsigned char purple[] = { 255,0,255 }; // Define a purple color |
philpem@5 | 120 | img.draw_text("Hello World",100,100,purple); // Draw a purple "Hello world" at coordinates (100,100). |
philpem@5 | 121 | img.display("My first CImg code"); // Display the image in a display window. |
philpem@5 | 122 | return 0; |
philpem@5 | 123 | } |
philpem@5 | 124 | \endcode |
philpem@5 | 125 | |
philpem@5 | 126 | Which can be also written in a more compact way as : |
philpem@5 | 127 | |
philpem@5 | 128 | \code |
philpem@5 | 129 | #include "CImg.h" |
philpem@5 | 130 | using namespace cimg_library; |
philpem@5 | 131 | |
philpem@5 | 132 | int main() { |
philpem@5 | 133 | const unsigned char purple[] = { 255,0,255 }; |
philpem@5 | 134 | CImg<unsigned char>(640,400,1,3,0).draw_text("Hello World",100,100,purple).display("My first CImg code"); |
philpem@5 | 135 | return 0; |
philpem@5 | 136 | } |
philpem@5 | 137 | \endcode |
philpem@5 | 138 | |
philpem@5 | 139 | Generally, you can write very small code that performs complex image processing tasks. The %CImg Library is very simple |
philpem@5 | 140 | to use and provide a lot of interesting algorithms for image manipulation. |
philpem@5 | 141 | |
philpem@5 | 142 | \section s3 How to compile ? |
philpem@5 | 143 | |
philpem@5 | 144 | The CImg library is a very light and user-friendly library : only standard system libraries are used. |
philpem@5 | 145 | It avoid to handle complex dependancies and problems with library compatibility. |
philpem@5 | 146 | The only thing you need is a (quite modern) C++ compiler : |
philpem@5 | 147 | |
philpem@5 | 148 | - <b>Microsoft Visual C++ 6.0, Visual Studio.NET and Visual Express Edition</b> : Use project files and solution files provided in the |
philpem@5 | 149 | %CImg Library package (directory 'compilation/') to see how it works. |
philpem@5 | 150 | - <b>Intel ICL compiler</b> : Use the following command to compile a CImg-based program with ICL : |
philpem@5 | 151 | \code |
philpem@5 | 152 | icl /Ox hello_world.cpp user32.lib gdi32.lib |
philpem@5 | 153 | \endcode |
philpem@5 | 154 | - <b>g++ (MingW windows version)</b> : Use the following command to compile a CImg-based program with g++, on Windows : |
philpem@5 | 155 | \code |
philpem@5 | 156 | g++ -o hello_word.exe hello_word.cpp -O2 -lgdi32 |
philpem@5 | 157 | \endcode |
philpem@5 | 158 | - <b>g++ (Linux version)</b> : Use the following command to compile a CImg-based program with g++, on Linux : |
philpem@5 | 159 | \code |
philpem@5 | 160 | g++ -o hello_word.exe hello_world.cpp -O2 -L/usr/X11R6/lib -lm -lpthread -lX11 |
philpem@5 | 161 | \endcode |
philpem@5 | 162 | - <b>g++ (Solaris version)</b> : Use the following command to compile a CImg-based program with g++, on Solaris : |
philpem@5 | 163 | \code |
philpem@5 | 164 | g++ -o hello_word.exe hello_world.cpp -O2 -lm -lpthread -R/usr/X11R6/lib -lrt -lnsl -lsocket |
philpem@5 | 165 | \endcode |
philpem@5 | 166 | - <b>g++ (Mac OS X version)</b> : Use the following command to compile a CImg-based program with g++, on Mac OS X : |
philpem@5 | 167 | \code |
philpem@5 | 168 | g++ -o hello_word.exe hello_world.cpp -O2 -lm -lpthread -L/usr/X11R6/lib -lm -lpthread -lX11 |
philpem@5 | 169 | \endcode |
philpem@5 | 170 | - <b>Dev-Cpp</b> : Use the project file provided in the CImg library package to see how it works. |
philpem@5 | 171 | |
philpem@5 | 172 | If you are using another compilers and encounter problems, please |
philpem@5 | 173 | <a href="http://www.greyc.ensicaen.fr/~dtschump">write me</a> since maintaining compatibility is one |
philpem@5 | 174 | of the priority of the %CImg Library. Nevertheless, old compilers that does not respect the C++ norm will not |
philpem@5 | 175 | support the %CImg Library. |
philpem@5 | 176 | |
philpem@5 | 177 | \section s4 What's next ? |
philpem@5 | 178 | |
philpem@5 | 179 | If you are ready to get more, and to start writing more serious programs |
philpem@5 | 180 | with CImg, you are invited to go to the \ref cimg_tutorial section. |
philpem@5 | 181 | |
philpem@5 | 182 | **/ |
philpem@5 | 183 | /*@}*/ |
philpem@5 | 184 | |
philpem@5 | 185 | /*---------------------------------- |
philpem@5 | 186 | |
philpem@5 | 187 | CImg<T> : The image structure |
philpem@5 | 188 | |
philpem@5 | 189 | --------------------------------*/ |
philpem@5 | 190 | |
philpem@5 | 191 | /** \addtogroup cimg_structure CImg<T> : The image structure. */ |
philpem@5 | 192 | /*@{*/ |
philpem@5 | 193 | /** |
philpem@5 | 194 | Description of the CImg<T> structure |
philpem@5 | 195 | |
philpem@5 | 196 | \page foo_cs |
philpem@5 | 197 | |
philpem@5 | 198 | \section cs0 Structure overview |
philpem@5 | 199 | |
philpem@5 | 200 | \section cs1 Image construction/destruction/copy |
philpem@5 | 201 | |
philpem@5 | 202 | \section cs2 Image methods |
philpem@5 | 203 | |
philpem@5 | 204 | \section cs3 Shared images |
philpem@5 | 205 | |
philpem@5 | 206 | \section cs4 Low-level structure |
philpem@5 | 207 | |
philpem@5 | 208 | **/ |
philpem@5 | 209 | /*@}*/ |
philpem@5 | 210 | |
philpem@5 | 211 | /*---------------------------------------- |
philpem@5 | 212 | |
philpem@5 | 213 | CImgList<T> : The image list structure |
philpem@5 | 214 | |
philpem@5 | 215 | ---------------------------------------*/ |
philpem@5 | 216 | |
philpem@5 | 217 | /** \addtogroup cimglist_structure CImgList<T> : The image list structure. */ |
philpem@5 | 218 | /*@{*/ |
philpem@5 | 219 | /** |
philpem@5 | 220 | Description of the CImgList<T> structure |
philpem@5 | 221 | |
philpem@5 | 222 | \page foo_cls |
philpem@5 | 223 | |
philpem@5 | 224 | \section cls0 Structure overview |
philpem@5 | 225 | |
philpem@5 | 226 | \section cls1 Image list construction/destruction/copy |
philpem@5 | 227 | |
philpem@5 | 228 | \section cls2 Image methods |
philpem@5 | 229 | |
philpem@5 | 230 | \section cls4 Low-level structure |
philpem@5 | 231 | |
philpem@5 | 232 | **/ |
philpem@5 | 233 | /*@}*/ |
philpem@5 | 234 | |
philpem@5 | 235 | /*---------------------------------------------- |
philpem@5 | 236 | |
philpem@5 | 237 | CImgDisplay : The image display structure |
philpem@5 | 238 | |
philpem@5 | 239 | --------------------------------------------*/ |
philpem@5 | 240 | |
philpem@5 | 241 | /** \addtogroup cimgdisplay_structure CImgDisplay : The image display structure. */ |
philpem@5 | 242 | /*@{*/ |
philpem@5 | 243 | /** |
philpem@5 | 244 | Description of the CImgDisplay structure |
philpem@5 | 245 | |
philpem@5 | 246 | \page foo_cds |
philpem@5 | 247 | |
philpem@5 | 248 | \section cds0 Structure overview |
philpem@5 | 249 | |
philpem@5 | 250 | \section cds1 Image display construction/destruction/copy |
philpem@5 | 251 | |
philpem@5 | 252 | \section cds2 Image methods |
philpem@5 | 253 | |
philpem@5 | 254 | \section cds4 Low-level structure |
philpem@5 | 255 | |
philpem@5 | 256 | **/ |
philpem@5 | 257 | /*@}*/ |
philpem@5 | 258 | |
philpem@5 | 259 | /*---------------------------------------------- |
philpem@5 | 260 | |
philpem@5 | 261 | CImgException : The library exception structure |
philpem@5 | 262 | |
philpem@5 | 263 | --------------------------------------------*/ |
philpem@5 | 264 | |
philpem@5 | 265 | /** \addtogroup cimgexception_structure CImgException : The library exception structure. */ |
philpem@5 | 266 | /*@{*/ |
philpem@5 | 267 | /** |
philpem@5 | 268 | Description of the CImgException structure |
philpem@5 | 269 | |
philpem@5 | 270 | \page foo_ces |
philpem@5 | 271 | |
philpem@5 | 272 | \section ces0 Structure overview |
philpem@5 | 273 | |
philpem@5 | 274 | |
philpem@5 | 275 | **/ |
philpem@5 | 276 | /*@}*/ |
philpem@5 | 277 | |
philpem@5 | 278 | |
philpem@5 | 279 | /*----------------------------------- |
philpem@5 | 280 | |
philpem@5 | 281 | FAQ : Frequently Asked Questions |
philpem@5 | 282 | |
philpem@5 | 283 | -------------------------------------*/ |
philpem@5 | 284 | |
philpem@5 | 285 | /** \addtogroup cimg_faq FAQ : Frequently Asked Questions. */ |
philpem@5 | 286 | /*@{*/ |
philpem@5 | 287 | /** |
philpem@5 | 288 | \page foofaq |
philpem@5 | 289 | |
philpem@5 | 290 | \section ssf0 FAQ Summary |
philpem@5 | 291 | |
philpem@5 | 292 | - <a href="#sf1">General information and availability</a> |
philpem@5 | 293 | - <a href="#ssf11">What is the CImg Library ?</a> |
philpem@5 | 294 | - <a href="#ssf12">What platforms are supported ?</a> |
philpem@5 | 295 | - <a href="#ssf13">How is CImg distributed ?</a> |
philpem@5 | 296 | - <a href="#ssf14">What kind of people are concerned by CImg ?</a> |
philpem@5 | 297 | - <a href="#ssf15">What are the specificities of the CeCILL license ?</a> |
philpem@5 | 298 | - <a href="#ssf16">Who is behind CImg ?</a> |
philpem@5 | 299 | |
philpem@5 | 300 | - <a href="#sf2">C++ related questions</a> |
philpem@5 | 301 | - <a href="#ssf21">What is the level of C++ knowledge needed to use CImg ?</a> |
philpem@5 | 302 | - <a href="#ssf22">How to use CImg in my own C++ program ?</a> |
philpem@5 | 303 | - <a href="#ssf23">Why is CImg entirely contained in a single header file ?</a> |
philpem@5 | 304 | |
philpem@5 | 305 | \section sf1 1. General information and availability |
philpem@5 | 306 | |
philpem@5 | 307 | \subsection ssf11 1.1. What is the CImg Library ? |
philpem@5 | 308 | |
philpem@5 | 309 | The CImg Library is an <i>open-source C++ toolkit for image processing</i>.\n |
philpem@5 | 310 | |
philpem@5 | 311 | It mainly consists in a (big) single header file |
philpem@5 | 312 | <a href="http://cimg.cvs.sourceforge.net/cimg/CImg/CImg.h?view=markup">CImg.h</a> |
philpem@5 | 313 | providing a set of C++ classes and functions that can be used in your own sources, |
philpem@5 | 314 | to load/save, manage/process and display generic images. |
philpem@5 | 315 | It's actually a very simple and pleasant toolkit for coding image processing stuffs in C++ : |
philpem@5 | 316 | Just include the header file <i>CImg.h</i>, and you are ready to handle images in your C++ programs. |
philpem@5 | 317 | |
philpem@5 | 318 | \subsection ssf12 1.2. What platforms are supported ? |
philpem@5 | 319 | |
philpem@5 | 320 | CImg has been designed with <i>portability</i> in mind. |
philpem@5 | 321 | It is regularly tested on different architectures and compilers, |
philpem@5 | 322 | and should also work on any decent OS having a decent C++ compiler. |
philpem@5 | 323 | Before each release, the CImg Library is compiled under these different configurations : |
philpem@5 | 324 | \li PC Linux 32 bits, with g++. |
philpem@5 | 325 | \li PC Windows 32 bits, with Visual C++ 6.0. |
philpem@5 | 326 | \li PC Windows 32 bits, with Visual C++ Express Edition. |
philpem@5 | 327 | \li Sun SPARC Solaris 32 bits, with g++. |
philpem@5 | 328 | \li Mac PPC with OS X and g++. |
philpem@5 | 329 | |
philpem@5 | 330 | CImg has a minimal number of dependencies. In its minimal version, it can be compiled only with standard C++ headers. |
philpem@5 | 331 | Anyway, it has interesting extension capabilities and can use external libraries to perform specific tasks more |
philpem@5 | 332 | efficiently (Fourier Transform computation using FFTW for instance). |
philpem@5 | 333 | |
philpem@5 | 334 | \subsection ssf13 1.3. How is CImg distributed ? |
philpem@5 | 335 | |
philpem@5 | 336 | The CImg Library is freely distributed as a complete .zip compressed package, hosted at the |
philpem@5 | 337 | <a href="http://sourceforge.net/project/showfiles.php?group_id=96492">Sourceforge servers</a>.\n |
philpem@5 | 338 | The package is distributed under the <a href="http://www.cecill.info">CeCILL license</a>. |
philpem@5 | 339 | |
philpem@5 | 340 | This package contains : |
philpem@5 | 341 | - The main library file <a href="http://cimg.cvs.sourceforge.net/cimg/CImg/CImg.h?view=markup">CImg.h</a> (C++ header file). |
philpem@5 | 342 | - Several C++ source code showing <a href="http://cimg.cvs.sourceforge.net/cimg/CImg/examples/">examples of using CImg</a>. |
philpem@5 | 343 | - A complete library documentation, in <a href="index.html">HTML</a> and <a href="../CImg_reference.pdf">PDF</a> formats. |
philpem@5 | 344 | - Additional <a href="http://cimg.cvs.sourceforge.net/cimg/CImg/plugins/">library plug-ins</a> that can be used to extend |
philpem@5 | 345 | library capabilities for specific uses. |
philpem@5 | 346 | |
philpem@5 | 347 | The CImg Library is a quite lightweight library which is easy to maintain (due to its particular structure), and thus |
philpem@5 | 348 | has a fast rythm of release. A new version of the CImg package is released approximately every three months. |
philpem@5 | 349 | |
philpem@5 | 350 | \subsection ssf14 1.4. What kind of people are concerned by CImg ? |
philpem@5 | 351 | |
philpem@5 | 352 | The CImg library is an <i>image processing</i> library, primarily intended for computer scientists or students working in the fields |
philpem@5 | 353 | of image processing or computer vision, and knowing bases of C++. |
philpem@5 | 354 | As the library is handy and really easy to use, it can be also used by any programmer |
philpem@5 | 355 | needing occasional tools for dealing with images in C++, since there are no standard library yet |
philpem@5 | 356 | for this purpose. |
philpem@5 | 357 | |
philpem@5 | 358 | \subsection ssf15 1.5. What are the specificities of the CeCILL license ? |
philpem@5 | 359 | |
philpem@5 | 360 | The <a href="http://www.cecill.info">CeCILL license</a> governs the use of the CImg Library. |
philpem@5 | 361 | This is an <i>open-source</i> license which gives you rights to access, use, modify and redistribute the source code, |
philpem@5 | 362 | under certains conditions. |
philpem@5 | 363 | There are two different variants of the CeCILL license used in CImg |
philpem@5 | 364 | (namely |
philpem@5 | 365 | <a href="http://www.cecill.info/licences/Licence_CeCILL_V2-en.html">CeCILL</a> and |
philpem@5 | 366 | <a href="http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html">CeCILL-C</a>, all open-source), |
philpem@5 | 367 | corresponding to different constraints on the source files : |
philpem@5 | 368 | - The <a href="http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html">CeCILL-C</a> license is the most permissive one, close to |
philpem@5 | 369 | the <i>GNU LGPL license</i>, and <i>applies <b>only</b> on the main library file |
philpem@5 | 370 | <a href="http://cimg.cvs.sourceforge.net/cimg/CImg/CImg.h?view=markup">CImg.h</a></i>. |
philpem@5 | 371 | Basically, this license allows to use <a href="http://cimg.cvs.sourceforge.net/cimg/CImg/CImg.h?view=markup">CImg.h</a> |
philpem@5 | 372 | in a closed-source product without forcing you to redistribute the entire software source code. Anyway, |
philpem@5 | 373 | if one modifies the <a href="http://cimg.cvs.sourceforge.net/cimg/CImg/CImg.h?view=markup">CImg.h</a> source file, one has to redistribute |
philpem@5 | 374 | the modified version of the file that must be governed by the same <a href="http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html">CeCILL-C</a> license. |
philpem@5 | 375 | |
philpem@5 | 376 | - The <a href="http://www.cecill.info/licences/Licence_CeCILL_V2-en.html">CeCILL</a> license applies to all other files |
philpem@5 | 377 | (source examples, plug-ins and documentation) of the CImg Library package, and is close (even <i>compatible</i>) |
philpem@5 | 378 | with the <i>GNU GPL license</i>. It <i>does not allow</i> the use of these files in closed-source products. |
philpem@5 | 379 | |
philpem@5 | 380 | You are invited to read the complete descriptions of the |
philpem@5 | 381 | the <a href="http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html">CeCILL-C</a> |
philpem@5 | 382 | and <a href="http://www.cecill.info/licences/Licence_CeCILL_V2-en.html">CeCILL</a> licenses before releasing a |
philpem@5 | 383 | software based on the CImg Library. |
philpem@5 | 384 | |
philpem@5 | 385 | \subsection ssf16 1.6. Who is behind CImg ? |
philpem@5 | 386 | |
philpem@5 | 387 | CImg has been started by |
philpem@5 | 388 | <a href="http://www.greyc.ensicaen.fr/~dtschump/">David Tschumperle</a> at the beginning of his PhD thesis, in October 1999. |
philpem@5 | 389 | He is still the main coordinator of the project. |
philpem@5 | 390 | Since the first release at Sourceforge, a growing number of contributors has appeared. |
philpem@5 | 391 | Due to the very simple and compact form of the library, submitting a contribution is quite easy and can be |
philpem@5 | 392 | fastly integrated into the supported releases. |
philpem@5 | 393 | List of contributors can be found on the front page. |
philpem@5 | 394 | |
philpem@5 | 395 | \section sf2 2. C++ related questions |
philpem@5 | 396 | |
philpem@5 | 397 | \subsection ssf21 2.1 What is the level of C++ knowledge needed to use CImg ? |
philpem@5 | 398 | |
philpem@5 | 399 | The CImg Library has been designed using C++ templates and object-oriented programming techniques, |
philpem@5 | 400 | but in a very accessible level. |
philpem@5 | 401 | There are only public classes without any derivation (just like C structures) and |
philpem@5 | 402 | there is at most one template parameter for each CImg class (defining the pixel type of the images). |
philpem@5 | 403 | The design is simple but clean, making the library accessible even for non professional C++ programmers, while proposing |
philpem@5 | 404 | strong extension capabilities for C++ experts. |
philpem@5 | 405 | |
philpem@5 | 406 | \subsection ssf22 2.2 How to use CImg in my own C++ program ? |
philpem@5 | 407 | |
philpem@5 | 408 | Basically, you need to add these two lines in your C++ source code, in order |
philpem@5 | 409 | to be able to work with CImg images : |
philpem@5 | 410 | \code |
philpem@5 | 411 | #include "CImg.h" |
philpem@5 | 412 | using namespace cimg_library; |
philpem@5 | 413 | \endcode |
philpem@5 | 414 | |
philpem@5 | 415 | \subsection ssf23 2.3 Why is CImg entirely contained in a single header file ? |
philpem@5 | 416 | |
philpem@5 | 417 | People are often surprised to see that the complete code of the library is contained in a single (big) C++ header file |
philpem@5 | 418 | <a href="http://cimg.cvs.sourceforge.net/cimg/CImg/CImg.h?view=markup">CImg.h</a>. |
philpem@5 | 419 | There are good practical and technical reasons to do that. Some arguments are listed below to justify this approach, |
philpem@5 | 420 | so (I hope) you won't think this is a awkwardly C++ design of the CImg library :\n |
philpem@5 | 421 | |
philpem@5 | 422 | - First, the library is based on <i>template datatypes</i> (images with generic pixel type), |
philpem@5 | 423 | meaning that the programmer is free to decide what type of image he instanciates in his code. |
philpem@5 | 424 | Even if there are roughly a limited number of fully supported types (basically, the "atomic" types of C++ : <i>unsigned char, int, float, ...</i>), |
philpem@5 | 425 | this is <i>not imaginable</i> to pre-compile the library classes and functions for <i>all possible atomic datatypes</i>, |
philpem@5 | 426 | since many functions and methods can have two or three arguments having different template parameters. |
philpem@5 | 427 | This really means <i>a huge number</i> of possible combinations. The size of the object binary file generated to cover all possible cases |
philpem@5 | 428 | would be just <i>colossal</i>. Is the STL library a pre-compiled one ? No, CImg neither. |
philpem@5 | 429 | CImg is not using a classical <i>.cpp</i> and <i>.h</i> mechanism, just like the STL. |
philpem@5 | 430 | Architectures of C++ <i>template-based</i> libraries are somewhat special in this sense. This is a proven technical fact. |
philpem@5 | 431 | |
philpem@5 | 432 | - Second, why CImg does not have several header files, just like the STL does (one for each class for instance) ? |
philpem@5 | 433 | This would be possible of course. |
philpem@5 | 434 | There are only 4 classes in CImg, the two most important being <i>CImg<T></i> and <i>CImgList<T></i> representing respectively |
philpem@5 | 435 | an image and a collection of images. |
philpem@5 | 436 | But contrary to the STL library, these two CImg classes are strongly <i>inter-dependent</i>. All CImg algorithms |
philpem@5 | 437 | are actually not defined as separate functions acting on containers (as the STL does with his header <algorithm>), |
philpem@5 | 438 | but are directly methods of the image and image collection classes. This inter-dependence practically means that you |
philpem@5 | 439 | will undoubtly need these two main classes at the same time if you are using CImg. |
philpem@5 | 440 | If they were defined in separate header files, you would be forced to include both of them. What is the gain then ? No gain.\n |
philpem@5 | 441 | Concerning the two other classes : You can disable the third most important class <i>CImgDisplay</i> of the CImg library, by setting the compilation |
philpem@5 | 442 | macro <i>cimg_display</i> to 0, avoiding thus to compile this class if you don't use display capabilities of CImg in your code. |
philpem@5 | 443 | But to be honest, this is a quite small class and doing this doesn't save much compilation time. |
philpem@5 | 444 | The last and fourth class is <i>CImgException</i>, which is only few lines long and is obviously required in almost all methods of CImg. |
philpem@5 | 445 | Including this one is <i>mandatory</i>.\n |
philpem@5 | 446 | As a consequence, having a single header file instead of several ones is just a way for you to avoid including all of them, |
philpem@5 | 447 | without any consequences on compilation time. This is both good technical and practical reasons to do like this. |
philpem@5 | 448 | |
philpem@5 | 449 | - Third, having a single header file has plenty of advantages : Simplicity for the user, and for the developers (maintenance is in fact easier). |
philpem@5 | 450 | Look at the <i>CImg.h</i> file, it looks like a mess at a first glance, but it is in fact very well organized and structured. |
philpem@5 | 451 | Finding pieces of code in CImg functions or methods is particularly easy and fast. |
philpem@5 | 452 | Also, how about the fact that library installation problems just disappear ? |
philpem@5 | 453 | Just bring <i>CImg.h</i> with you, put it in your source directory, and the library is ready to go ! |
philpem@5 | 454 | |
philpem@5 | 455 | I admit the compilation time of CImg-based programs can be sometime long, but don't think that it is due to the fact that you are |
philpem@5 | 456 | using a single header file. Using several header files wouldn't arrange anything since you would need all of them. |
philpem@5 | 457 | Having a pre-compiled library object would be the only solution to speed up compilation time, but it is not possible at all, |
philpem@5 | 458 | due to the too much generic nature of the library. |
philpem@5 | 459 | Think seriously about it, and if you have a better solution to provide, let me know so we can discuss about it. |
philpem@5 | 460 | |
philpem@5 | 461 | **/ |
philpem@5 | 462 | /*@}*/ |
philpem@5 | 463 | |
philpem@5 | 464 | /*----------------------------------- |
philpem@5 | 465 | |
philpem@5 | 466 | Setting Environment Variables |
philpem@5 | 467 | |
philpem@5 | 468 | -------------------------------------*/ |
philpem@5 | 469 | |
philpem@5 | 470 | /** \addtogroup cimg_environment Setting Environment Variables */ |
philpem@5 | 471 | /*@{*/ |
philpem@5 | 472 | /** |
philpem@5 | 473 | \page foo1 |
philpem@5 | 474 | |
philpem@5 | 475 | The CImg library is a multiplatform library, working on a wide variety of systems. |
philpem@5 | 476 | This implies the existence of some \e environment \e variables that must be correctly defined |
philpem@5 | 477 | depending on your current system. |
philpem@5 | 478 | Most of the time, the %CImg Library defines these variables automatically |
philpem@5 | 479 | (for popular systems). Anyway, if your system is not recognized, you will have to set the environment |
philpem@5 | 480 | variables by hand. Here is a quick explanations of environment variables.\n |
philpem@5 | 481 | |
philpem@5 | 482 | Setting the environment variables is done with the <tt>#define</tt> keyword. |
philpem@5 | 483 | This setting must be done <i>before including the file CImg.h</i> in your source code. |
philpem@5 | 484 | For instance, |
philpem@5 | 485 | defining the environment variable \c cimg_display would be done like this : |
philpem@5 | 486 | \code |
philpem@5 | 487 | #define cimg_display 0 |
philpem@5 | 488 | #include "CImg.h" |
philpem@5 | 489 | ... |
philpem@5 | 490 | \endcode |
philpem@5 | 491 | |
philpem@5 | 492 | Here are the different environment variables used by the %CImg Library : |
philpem@5 | 493 | |
philpem@5 | 494 | - \b \c cimg_OS : This variable defines the type of your Operating System. It can be set to \b 1 (\e Unix), |
philpem@5 | 495 | \b 2 (\e Windows), or \b 0 (\e Other \e configuration). |
philpem@5 | 496 | It should be actually auto-detected by the CImg library. If this is not the case (<tt>cimg_OS=0</tt>), you |
philpem@5 | 497 | will probably have to tune the environment variables described below. |
philpem@5 | 498 | |
philpem@5 | 499 | - \b \c cimg_display : This variable defines the type of graphical library used to |
philpem@5 | 500 | display images in windows. It can be set to 0 (no display library available), \b 1 (X11-based display) or |
philpem@5 | 501 | \b 2 (Windows-GDI display). |
philpem@5 | 502 | If you are running on a system without X11 or Windows-GDI ability, please set this variable to \c 0. |
philpem@5 | 503 | This will disable the display support, since the %CImg Library doesn't contain the necessary code to display |
philpem@5 | 504 | images on systems other than X11 or Windows GDI. |
philpem@5 | 505 | |
philpem@5 | 506 | - \b \c cimg_color_terminal : This variable tells the library if the system terminal has VT100 color capabilities. |
philpem@5 | 507 | It can be \e defined or \e not \e defined. Define this variable to get colored output on your terminal, |
philpem@5 | 508 | when using the %CImg Library. |
philpem@5 | 509 | |
philpem@5 | 510 | - \b \c cimg_debug : This variable defines the level of run-time debug messages that will be displayed by |
philpem@5 | 511 | the %CImg Library. It can be set to 0 (no debug messages), 1 (normal debug messages displayed on |
philpem@5 | 512 | standard error), 2 (normal debug messages displayed in modal windows, which is |
philpem@5 | 513 | the default value), or 3 (high debug messages). Note that setting this value to 3 may slow down your |
philpem@5 | 514 | program since more debug tests are made by the library (particularly to check if pixel access is made outside |
philpem@5 | 515 | image boundaries). See also CImgException to better understand how debug messages are working. |
philpem@5 | 516 | |
philpem@5 | 517 | - \b \c cimg_convert_path : This variables tells the library where the ImageMagick's \e convert tool is located. |
philpem@5 | 518 | Setting this variable should not be necessary if ImageMagick is installed on a standard directory, or |
philpem@5 | 519 | if \e convert is in your system PATH variable. This macro should be defined only if the ImageMagick's |
philpem@5 | 520 | \e convert tool is not found automatically, when trying to read compressed image format (GIF,PNG,...). |
philpem@5 | 521 | See also cimg_library::CImg::get_load_convert() and cimg_library::CImg::save_convert() for more informations. |
philpem@5 | 522 | |
philpem@5 | 523 | - \b \c cimg_temporary_path : This variable tells the library where it can find a directory to store |
philpem@5 | 524 | temporary files. Setting this variable should not be necessary if you are running on a standard system. |
philpem@5 | 525 | This macro should be defined only when troubles are encountered when trying to read |
philpem@5 | 526 | compressed image format (GIF,PNG,...). |
philpem@5 | 527 | See also cimg_library::CImg::get_load_convert() and cimg_library::CImg::save_convert() for more informations. |
philpem@5 | 528 | |
philpem@5 | 529 | - \b \c cimg_plugin : This variable tells the library to use a plugin file to add features to the CImg<T> class. |
philpem@5 | 530 | Define it with the path of your plugin file, if you want to add member functions to the CImg<T> class, |
philpem@5 | 531 | without having to modify directly the \c "CImg.h" file. An include of the plugin file is performed in the CImg<T> |
philpem@5 | 532 | class. If \c cimg_plugin if not specified (default), no include is done. |
philpem@5 | 533 | |
philpem@5 | 534 | - \b \c cimglist_plugin : Same as \c cimg_plugin, but to add features to the CImgList<T> class. |
philpem@5 | 535 | |
philpem@5 | 536 | - \b \c cimgdisplay_plugin : Same as \c cimg_plugin, but to add features to the CImgDisplay<T> class. |
philpem@5 | 537 | |
philpem@5 | 538 | All these compilation variables can be checked, using the function cimg_library::cimg::info(), which |
philpem@5 | 539 | displays a list of the different configuration variables and their values on the standard error output. |
philpem@5 | 540 | **/ |
philpem@5 | 541 | /*@}*/ |
philpem@5 | 542 | |
philpem@5 | 543 | /*----------------------------------- |
philpem@5 | 544 | |
philpem@5 | 545 | Using drawing functions |
philpem@5 | 546 | |
philpem@5 | 547 | -------------------------------------*/ |
philpem@5 | 548 | |
philpem@5 | 549 | /** \addtogroup cimg_visual2005 How to use CImg library with Visual C++ 2005 Express Edition ?. */ |
philpem@5 | 550 | /*@{*/ |
philpem@5 | 551 | /** |
philpem@5 | 552 | \page foo89198 |
philpem@5 | 553 | |
philpem@5 | 554 | \section s13968 How to use CImg library with Visual C++ 2005 Express Edition ? |
philpem@5 | 555 | |
philpem@5 | 556 | This section has been written by Vincent Garcia and Alexandre Fournier from I3S/Sophia_Antipolis. |
philpem@5 | 557 | |
philpem@5 | 558 | - Download CImg library |
philpem@5 | 559 | - Download and install Visual C++ 2005 Express Edition |
philpem@5 | 560 | - Download and install Microsoft Windows SDK |
philpem@5 | 561 | - Configure Visual C++ to take into account Microsoft SDK |
philpem@5 | 562 | - 1. Go to menu "Tools -> options" |
philpem@5 | 563 | - 2. Select option "Projects and Solutions -> VC++ Directories" |
philpem@5 | 564 | - 3. In the select liste "Show directories for", choose "include files", and add C:\Program Files\Microsoft Platform SDK\Include (adapt if needed) |
philpem@5 | 565 | - 4. In the select liste "Show directories for", choose "library files", and add C:\Program Files\Microsoft Platform SDK\Lib |
philpem@5 | 566 | (adapt if needed) Edit file C:\Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults\corewin_express.vsprops (adapt if needed) |
philpem@5 | 567 | - 6. 7. Remplace the line AdditionalDependencies="kernel32.lib" /> by AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib" /> |
philpem@5 | 568 | - Restart Visual C++ |
philpem@5 | 569 | - Import CImg library in your main file |
philpem@5 | 570 | |
philpem@5 | 571 | **/ |
philpem@5 | 572 | /*@}*/ |
philpem@5 | 573 | |
philpem@5 | 574 | |
philpem@5 | 575 | /*----------------------------------- |
philpem@5 | 576 | |
philpem@5 | 577 | Tutorial : Getting started |
philpem@5 | 578 | |
philpem@5 | 579 | -------------------------------------*/ |
philpem@5 | 580 | |
philpem@5 | 581 | /** \addtogroup cimg_tutorial Tutorial : Getting Started. */ |
philpem@5 | 582 | /*@{*/ |
philpem@5 | 583 | /** |
philpem@5 | 584 | \page foo3 |
philpem@5 | 585 | |
philpem@5 | 586 | Let's start to write our first program to get the idea. This will demonstrate how to load and create images, as well as handle image |
philpem@5 | 587 | display and mouse events. |
philpem@5 | 588 | Assume we want to load a color image <tt>lena.jpg</tt>, smooth it, display it in a windows, and enter an event loop so that clicking a |
philpem@5 | 589 | point in the image will draw the (R,G,B) intensity profiles of the corresponding image line (in another window). |
philpem@5 | 590 | Yes, that sounds quite complex for a first code, but don't worry, it will be very simple using the CImg library ! Well, just look |
philpem@5 | 591 | at the code below, it does the task : |
philpem@5 | 592 | |
philpem@5 | 593 | \code |
philpem@5 | 594 | #include "CImg.h" |
philpem@5 | 595 | using namespace cimg_library; |
philpem@5 | 596 | |
philpem@5 | 597 | int main() { |
philpem@5 | 598 | CImg<unsigned char> image("lena.jpg"), visu(500,400,1,3,0); |
philpem@5 | 599 | const unsigned char red[] = { 255,0,0 }, green[] = { 0,255,0 }, blue[] = { 0,0,255 }; |
philpem@5 | 600 | image.blur(2.5); |
philpem@5 | 601 | CImgDisplay main_disp(image,"Click a point"), draw_disp(visu,"Intensity profile"); |
philpem@5 | 602 | while (!main_disp.is_closed && !draw_disp.is_closed) { |
philpem@5 | 603 | main_disp.wait(); |
philpem@5 | 604 | if (main_disp.button && main_disp.mouse_y>=0) { |
philpem@5 | 605 | const int y = main_disp.mouse_y; |
philpem@5 | 606 | visu.fill(0).draw_graph(image.get_crop(0,y,0,0,image.dimx()-1,y,0,0),red,1,1,0,255,0); |
philpem@5 | 607 | visu.draw_graph(image.get_crop(0,y,0,1,image.dimx()-1,y,0,1),green,1,1,0,255,0); |
philpem@5 | 608 | visu.draw_graph(image.get_crop(0,y,0,2,image.dimx()-1,y,0,2),blue,1,1,0,255,0).display(draw_disp); |
philpem@5 | 609 | } |
philpem@5 | 610 | } |
philpem@5 | 611 | return 0; |
philpem@5 | 612 | } |
philpem@5 | 613 | \endcode |
philpem@5 | 614 | |
philpem@5 | 615 | Here is a screenshot of the resulting program : |
philpem@5 | 616 | |
philpem@5 | 617 | <img SRC="../img/tutorial.jpg"> |
philpem@5 | 618 | |
philpem@5 | 619 | And here is the detailled explanation of the source, line by line : |
philpem@5 | 620 | |
philpem@5 | 621 | \code #include "CImg.h" \endcode |
philpem@5 | 622 | Include the main and only header file of the CImg library. |
philpem@5 | 623 | \code using namespace cimg_library; \endcode |
philpem@5 | 624 | Use the library namespace to ease the declarations afterward. |
philpem@5 | 625 | \code int main() { \endcode |
philpem@5 | 626 | Definition of the main function. |
philpem@5 | 627 | \code CImg<unsigned char> image("lena.jpg"), visu(500,400,1,3,0); \endcode |
philpem@5 | 628 | Creation of two instances of images of \c unsigned \c char pixels. |
philpem@5 | 629 | The first image \c image is initialized by reading an image file from the disk. |
philpem@5 | 630 | Here, <tt>lena.jpg</tt> must be in the same directory than the current program. |
philpem@5 | 631 | Note that you must also have installed the \e ImageMagick package in order to be able to read JPG images. |
philpem@5 | 632 | The second image \c visu is initialized as a black color image with dimension <tt>dx=500</tt>, <tt>dy=400</tt>, |
philpem@5 | 633 | <tt>dz=1</tt> (here, it is a 2D image, not a 3D one), and <tt>dv=3</tt> (each pixel has 3 'vector' channels R,G,B). |
philpem@5 | 634 | The last argument in the constructor defines the default value of the pixel values |
philpem@5 | 635 | (here \c 0, which means that \c visu will be initially black). |
philpem@5 | 636 | \code const unsigned char red[] = { 255,0,0 }, green[] = { 0,255,0 }, blue[] = { 0,0,255 }; \endcode |
philpem@5 | 637 | Definition of three different colors as array of unsigned char. This will be used to draw plots with different colors. |
philpem@5 | 638 | \code image.blur(2.5); \endcode |
philpem@5 | 639 | Blur the image, with a gaussian blur and a standard variation of 2.5. Note that most of the CImg functions have two versions : |
philpem@5 | 640 | one that acts in-place (which is the case of blur), and one that returns the result as a new image (the name of the function |
philpem@5 | 641 | begins then with <tt>get_</tt> ). In this case, one could have also written <tt>image = image.get_blur(2.5);</tt> |
philpem@5 | 642 | (more expensive, since it needs an additional copy operation). |
philpem@5 | 643 | \code CImgDisplay main_disp(image,"Click a point"), draw_disp(visu,"Intensity profile"); \endcode |
philpem@5 | 644 | Creation of two display windows, one for the input image image, and one for the image visu which will be display intensity profiles. |
philpem@5 | 645 | By default, CImg displays handles events (mouse,keyboard,..). On Windows, there is a way to create fullscreen displays. |
philpem@5 | 646 | \code while (!main_disp.is_closed && !draw_disp.is_closed) { \endcode |
philpem@5 | 647 | Enter the event loop, the code will exit when one of the two display windows is closed. |
philpem@5 | 648 | \code main_disp.wait(); \endcode |
philpem@5 | 649 | Wait for an event (mouse, keyboard,..) in the display window \c main_disp. |
philpem@5 | 650 | \code if (main_disp.button && main_disp.mouse_y>=0) { \endcode |
philpem@5 | 651 | Test if the mouse button has been clicked on the image area. |
philpem@5 | 652 | One may distinguish between the 3 different mouse buttons, |
philpem@5 | 653 | but in this case it is not necessary |
philpem@5 | 654 | \code const int y = main_disp.mouse_y; \endcode |
philpem@5 | 655 | Get the image line y-coordinate that has been clicked. |
philpem@5 | 656 | \code visu.fill(0).draw_graph(image.get_crop(0,y,0,0,image.dimx()-1,y,0,0),red,1,0,256,0); \endcode |
philpem@5 | 657 | This line illustrates the pipeline property of most of the CImg class functions. The first function <tt>fill(0)</tt> simply sets |
philpem@5 | 658 | all pixel values with 0 (i.e. clear the image \c visu). The interesting thing is that it returns a reference to |
philpem@5 | 659 | \c visu and then, can be pipelined with the function \c draw_graph() which draws a plot in the image \c visu. |
philpem@5 | 660 | The plot data are given by another image (the first argument of \c draw_graph()). In this case, the given image is |
philpem@5 | 661 | the red-component of the line y of the original image, retrieved by the function \c get_crop() which returns a |
philpem@5 | 662 | sub-image of the image \c image. Remember that images coordinates are 4D (x,y,z,v) and for color images, |
philpem@5 | 663 | the R,G,B channels are respectively given by <tt>v=0, v=1</tt> and <tt>v=2</tt>. |
philpem@5 | 664 | \code visu.draw_graph(image.get_crop(0,y,0,1,image.dimx()-1,y,0,1),green,1,0,256,0); \endcode |
philpem@5 | 665 | Plot the intensity profile for the green channel of the clicked line. |
philpem@5 | 666 | \code visu.draw_graph(image.get_crop(0,y,0,2,image.dimx()-1,y,0,2),blue,1,0,256,0).display(draw_disp); \endcode |
philpem@5 | 667 | Same thing for the blue channel. Note how the function (which return a reference to \c visu) is pipelined with the function |
philpem@5 | 668 | \c display() that just paints the image visu in the corresponding display window. |
philpem@5 | 669 | \code ...till the end \endcode |
philpem@5 | 670 | I don't think you need more explanations ! |
philpem@5 | 671 | |
philpem@5 | 672 | As you have noticed, the CImg library allows to write very small and intuitive code. Note also that this source will perfectly |
philpem@5 | 673 | work on Unix and Windows systems. Take also a look to the examples provided in the CImg package ( |
philpem@5 | 674 | directory \c examples/ ). It will show you how CImg-based code can be surprisingly small. |
philpem@5 | 675 | Moreover, there is surely one example close to what you want to do. |
philpem@5 | 676 | A good start will be to look at the file <tt>CImg_demo.cpp</tt> which contains small and various examples of what you can do |
philpem@5 | 677 | with the %CImg Library. All CImg classes are used in this source, and the code can be easily modified to see what happens. |
philpem@5 | 678 | |
philpem@5 | 679 | **/ |
philpem@5 | 680 | /*@}*/ |
philpem@5 | 681 | |
philpem@5 | 682 | /*----------------------------------- |
philpem@5 | 683 | |
philpem@5 | 684 | Using drawing functions |
philpem@5 | 685 | |
philpem@5 | 686 | -------------------------------------*/ |
philpem@5 | 687 | |
philpem@5 | 688 | /** \addtogroup cimg_drawing Using Drawing Functions. */ |
philpem@5 | 689 | /*@{*/ |
philpem@5 | 690 | /** |
philpem@5 | 691 | \page foo5 |
philpem@5 | 692 | |
philpem@5 | 693 | \section s5 Using Drawing Functions. |
philpem@5 | 694 | |
philpem@5 | 695 | This section tells more about drawing features in CImg images. |
philpem@5 | 696 | Drawing functions list can be found in <a href="structCImg.html">the CImg functions list</a> |
philpem@5 | 697 | (section \b Drawing Functions), |
philpem@5 | 698 | and are all defined on a common basis. Here are the important points to understand before using |
philpem@5 | 699 | drawing functions : |
philpem@5 | 700 | |
philpem@5 | 701 | - Drawing is performed on the instance image. Drawing functions parameters |
philpem@5 | 702 | are defined as \e const variables and return a reference to the current instance <tt>(*this)</tt>, |
philpem@5 | 703 | so that drawing functions can be pipelined (see examples below). |
philpem@5 | 704 | Drawing is usually done in 2D color images but can be performed in 3D images with any vector-valued dimension, |
philpem@5 | 705 | and with any possible pixel type. |
philpem@5 | 706 | |
philpem@5 | 707 | - A color parameter is always needed to draw features in an image. The color must be defined as a C-style array |
philpem@5 | 708 | whose dimension is at least |
philpem@5 | 709 | |
philpem@5 | 710 | **/ |
philpem@5 | 711 | /*@}*/ |
philpem@5 | 712 | |
philpem@5 | 713 | /*----------------------------------- |
philpem@5 | 714 | |
philpem@5 | 715 | Using image loops |
philpem@5 | 716 | |
philpem@5 | 717 | -------------------------------------*/ |
philpem@5 | 718 | |
philpem@5 | 719 | /** \addtogroup cimg_loops Using Image Loops. */ |
philpem@5 | 720 | /*@{*/ |
philpem@5 | 721 | /** |
philpem@5 | 722 | \page foo_lo |
philpem@5 | 723 | The %CImg Library provides different macros that define useful iterative loops over an image. |
philpem@5 | 724 | Basically, it can be used to replace one or several <tt>for(..)</tt> instructions, but it also proposes |
philpem@5 | 725 | interesting extensions to classical loops. |
philpem@5 | 726 | Below is a list of all existing loop macros, classified in four different categories : |
philpem@5 | 727 | - \ref lo1 |
philpem@5 | 728 | - \ref lo4 |
philpem@5 | 729 | - \ref lo5 |
philpem@5 | 730 | - \ref lo6 |
philpem@5 | 731 | |
philpem@5 | 732 | \section lo1 Loops over the pixel buffer |
philpem@5 | 733 | |
philpem@5 | 734 | Loops over the pixel buffer are really basic loops that iterate a pointer on the pixel data buffer |
philpem@5 | 735 | of a \c cimg_library::CImg image. Two macros are defined for this purpose : |
philpem@5 | 736 | |
philpem@5 | 737 | - \b cimg_for(img,ptr,T) : |
philpem@5 | 738 | This macro loops over the pixel data buffer of the image \c img, using a pointer <tt>T* ptr</tt>, |
philpem@5 | 739 | starting from the end of the buffer (last pixel) till the beginning of the buffer (first pixel). |
philpem@5 | 740 | - \c img must be a (non empty) \c cimg_library::CImg image of pixels \c T. |
philpem@5 | 741 | - \c ptr is a pointer of type \c T*. |
philpem@5 | 742 | This kind of loop should not appear a lot in your own source code, since this is a low-level loop |
philpem@5 | 743 | and many functions of the CImg class may be used instead. Here is an example of use : |
philpem@5 | 744 | \code |
philpem@5 | 745 | CImg<float> img(320,200); |
philpem@5 | 746 | cimg_for(img,ptr,float) { *ptr=0; } // Equivalent to 'img.fill(0);' |
philpem@5 | 747 | \endcode |
philpem@5 | 748 | |
philpem@5 | 749 | - \b cimg_foroff(img,off) : |
philpem@5 | 750 | This macro loops over the pixel data buffer of the image \c img, using an offset \c , |
philpem@5 | 751 | starting from the beginning of the buffer (first pixel, \c off=0) |
philpem@5 | 752 | till the end of the buffer (last pixel value, <tt>off = img.size()-1</tt>). |
philpem@5 | 753 | - \c img must be a (non empty) cimg_library::CImg<T> image of pixels \c T. |
philpem@5 | 754 | - \c off is an inner-loop variable, only defined inside the scope of the loop. |
philpem@5 | 755 | |
philpem@5 | 756 | Here is an example of use : |
philpem@5 | 757 | \code |
philpem@5 | 758 | CImg<float> img(320,200); |
philpem@5 | 759 | cimg_foroff(img,off) { img[off]=0; } // Equivalent to 'img.fill(0);' |
philpem@5 | 760 | \endcode |
philpem@5 | 761 | |
philpem@5 | 762 | \section lo4 Loops over image dimensions |
philpem@5 | 763 | |
philpem@5 | 764 | The following loops are probably the most used loops in image processing programs. |
philpem@5 | 765 | They allow to loop over the image along one or several dimensions, along a raster scan course. |
philpem@5 | 766 | Here is the list of such loop macros for a single dimension : |
philpem@5 | 767 | - \b cimg_forX(img,x) : equivalent to : <tt>for (int x=0; x<img.dimx(); x++)</tt>. |
philpem@5 | 768 | - \b cimg_forY(img,y) : equivalent to : <tt>for (int y=0; y<img.dimy(); y++)</tt>. |
philpem@5 | 769 | - \b cimg_forZ(img,z) : equivalent to : <tt>for (int z=0; z<img.dimz(); z++)</tt>. |
philpem@5 | 770 | - \b cimg_forV(img,v) : equivalent to : <tt>for (int v=0; v<img.dimv(); v++)</tt>. |
philpem@5 | 771 | |
philpem@5 | 772 | Combinations of these macros are also defined as other loop macros, allowing to loop directly over 2D, 3D or 4D images : |
philpem@5 | 773 | - \b cimg_forXY(img,x,y) : equivalent to : \c cimg_forY(img,y) \c cimg_forX(img,x). |
philpem@5 | 774 | - \b cimg_forXZ(img,x,z) : equivalent to : \c cimg_forZ(img,z) \c cimg_forX(img,x). |
philpem@5 | 775 | - \b cimg_forYZ(img,y,z) : equivalent to : \c cimg_forZ(img,z) \c cimg_forY(img,y). |
philpem@5 | 776 | - \b cimg_forXV(img,x,v) : equivalent to : \c cimg_forV(img,v) \c cimg_forX(img,x). |
philpem@5 | 777 | - \b cimg_forYV(img,y,v) : equivalent to : \c cimg_forV(img,v) \c cimg_forY(img,y). |
philpem@5 | 778 | - \b cimg_forZV(img,z,v) : equivalent to : \c cimg_forV(img,v) \c cimg_forZ(img,z). |
philpem@5 | 779 | - \b cimg_forXYZ(img,x,y,z) : equivalent to : \c cimg_forZ(img,z) \c cimg_forXY(img,x,y). |
philpem@5 | 780 | - \b cimg_forXYV(img,x,y,v) : equivalent to : \c cimg_forV(img,v) \c cimg_forXY(img,x,y). |
philpem@5 | 781 | - \b cimg_forXZV(img,x,z,v) : equivalent to : \c cimg_forV(img,v) \c cimg_forXZ(img,x,z). |
philpem@5 | 782 | - \b cimg_forYZV(img,y,z,v) : equivalent to : \c cimg_forV(img,v) \c cimg_forYZ(img,y,z). |
philpem@5 | 783 | - \b cimg_forXYZV(img,x,y,z,v) : equivalent to : \c cimg_forV(img,v) \c cimg_forXYZ(img,x,y,z). |
philpem@5 | 784 | |
philpem@5 | 785 | - For all these loops, \c x,\c y,\c z and \c v are inner-defined variables only visible inside the scope of the loop. |
philpem@5 | 786 | They don't have to be defined before the call of the macro. |
philpem@5 | 787 | - \c img must be a (non empty) cimg_library::CImg image. |
philpem@5 | 788 | |
philpem@5 | 789 | Here is an example of use that creates an image with a smooth color gradient : |
philpem@5 | 790 | \code |
philpem@5 | 791 | CImg<unsigned char> img(256,256,1,3); // Define a 256x256 color image |
philpem@5 | 792 | cimg_forXYV(img,x,y,v) { img(x,y,v) = (x+y)*(v+1)/6; } |
philpem@5 | 793 | img.display("Color gradient"); |
philpem@5 | 794 | \endcode |
philpem@5 | 795 | |
philpem@5 | 796 | \section lo5 Loops over interior regions and borders. |
philpem@5 | 797 | |
philpem@5 | 798 | Similar macros are also defined to loop only on the border of an image, or inside the image (excluding the border). |
philpem@5 | 799 | The border may be several pixel wide : |
philpem@5 | 800 | |
philpem@5 | 801 | - \b cimg_for_insideX(img,x,n) : Loop along the x-axis, except for pixels inside a border of \p n pixels wide. |
philpem@5 | 802 | - \b cimg_for_insideY(img,y,n) : Loop along the y-axis, except for pixels inside a border of \p n pixels wide. |
philpem@5 | 803 | - \b cimg_for_insideZ(img,z,n) : Loop along the z-axis, except for pixels inside a border of \p n pixels wide. |
philpem@5 | 804 | - \b cimg_for_insideV(img,v,n) : Loop along the v-axis, except for pixels inside a border of \p n pixels wide. |
philpem@5 | 805 | - \b cimg_for_insideXY(img,x,y,n) : Loop along the (x,y)-axes, excepted for pixels inside a border of \p n pixels wide. |
philpem@5 | 806 | - \b cimg_for_insideXYZ(img,x,y,z,n) : Loop along the (x,y,z)-axes, excepted for pixels inside a border of \p n pixels wide. |
philpem@5 | 807 | |
philpem@5 | 808 | And also : |
philpem@5 | 809 | |
philpem@5 | 810 | - \b cimg_for_borderX(img,x,n) : Loop along the x-axis, only for pixels inside a border of \p n pixels wide. |
philpem@5 | 811 | - \b cimg_for_borderY(img,y,n) : Loop along the y-axis, only for pixels inside a border of \p n pixels wide. |
philpem@5 | 812 | - \b cimg_for_borderZ(img,z,n) : Loop along the z-axis, only for pixels inside a border of \p n pixels wide. |
philpem@5 | 813 | - \b cimg_for_borderV(img,v,n) : Loop along the z-axis, only for pixels inside a border of \p n pixels wide. |
philpem@5 | 814 | - \b cimg_for_borderXY(img,x,y,n) : Loop along the (x,y)-axes, only for pixels inside a border of \p n pixels wide. |
philpem@5 | 815 | - \b cimg_for_borderXYZ(img,x,y,z,n) : Loop along the (x,y,z)-axes, only for pixels inside a border of \p n pixels wide. |
philpem@5 | 816 | |
philpem@5 | 817 | - For all these loops, \c x,\c y,\c z and \c v are inner-defined variables only visible inside the scope of the loop. |
philpem@5 | 818 | They don't have to be defined before the call of the macro. |
philpem@5 | 819 | - \c img must be a (non empty) cimg_library::CImg image. |
philpem@5 | 820 | - The constant \c n stands for the size of the border. |
philpem@5 | 821 | |
philpem@5 | 822 | Here is an example of use, to create a 2d grayscale image with two different intensity gradients : |
philpem@5 | 823 | \code |
philpem@5 | 824 | CImg<> img(256,256); |
philpem@5 | 825 | cimg_for_insideXY(img,x,y,50) img(x,y) = x+y; |
philpem@5 | 826 | cimg_for_borderXY(img,x,y,50) img(x,y) = x-y; |
philpem@5 | 827 | img.display(); |
philpem@5 | 828 | \endcode |
philpem@5 | 829 | |
philpem@5 | 830 | \section lo6 Loops using neighborhoods. |
philpem@5 | 831 | |
philpem@5 | 832 | Inside an image loop, it is often useful to get values of neighborhood pixels of the |
philpem@5 | 833 | current pixel at the loop location. |
philpem@5 | 834 | The %CImg Library provides a very smart and fast mechanism for this purpose, with the definition |
philpem@5 | 835 | of several loop macros that remember the neighborhood values of the pixels. |
philpem@5 | 836 | The use of these macros can highly optimize your code, and also simplify your program. |
philpem@5 | 837 | |
philpem@5 | 838 | \subsection lo7 Neighborhood-based loops for 2D images |
philpem@5 | 839 | |
philpem@5 | 840 | For 2D images, the neighborhood-based loop macros are : |
philpem@5 | 841 | |
philpem@5 | 842 | - \b cimg_for2x2(img,x,y,z,v,I) : Loop along the (x,y)-axes using a centered 2x2 neighborhood. |
philpem@5 | 843 | - \b cimg_for3x3(img,x,y,z,v,I) : Loop along the (x,y)-axes using a centered 3x3 neighborhood. |
philpem@5 | 844 | - \b cimg_for4x4(img,x,y,z,v,I) : Loop along the (x,y)-axes using a centered 4x4 neighborhood. |
philpem@5 | 845 | - \b cimg_for5x5(img,x,y,z,v,I) : Loop along the (x,y)-axes using a centered 5x5 neighborhood. |
philpem@5 | 846 | |
philpem@5 | 847 | For all these loops, \c x and \c y are inner-defined variables only visible inside the scope of the loop. |
philpem@5 | 848 | They don't have to be defined before the call of the macro. |
philpem@5 | 849 | \c img is a non empty CImg<T> image. \c z and \c v are constants that define on which image slice and |
philpem@5 | 850 | vector channel the loop must apply (usually both 0 for grayscale 2D images). |
philpem@5 | 851 | Finally, \c I is the 2x2, 3x3, 4x4 or 5x5 neighborhood that will be updated with the correct pixel values |
philpem@5 | 852 | during the loop (see \ref lo9). |
philpem@5 | 853 | |
philpem@5 | 854 | \subsection lo8 Neighborhood-based loops for 3D images |
philpem@5 | 855 | |
philpem@5 | 856 | For 3D images, the neighborhood-based loop macros are : |
philpem@5 | 857 | |
philpem@5 | 858 | - \b cimg_for2x2x2(img,x,y,z,v,I) : Loop along the (x,y,z)-axes using a centered 2x2x2 neighborhood. |
philpem@5 | 859 | - \b cimg_for3x3x3(img,x,y,z,v,I) : Loop along the (x,y,z)-axes using a centered 3x3x3 neighborhood. |
philpem@5 | 860 | |
philpem@5 | 861 | For all these loops, \c x, \c y and \c z are inner-defined variables only visible inside the scope of the loop. |
philpem@5 | 862 | They don't have to be defined before the call of the macro. |
philpem@5 | 863 | \c img is a non empty CImg<T> image. \c v is a constant that defines on which image channel |
philpem@5 | 864 | the loop must apply (usually 0 for grayscale 3D images). |
philpem@5 | 865 | Finally, \c I is the 2x2x2 or 3x3x3 neighborhood that will be updated with the correct pixel values |
philpem@5 | 866 | during the loop (see \ref lo9). |
philpem@5 | 867 | |
philpem@5 | 868 | \subsection lo9 Defining neighborhoods |
philpem@5 | 869 | |
philpem@5 | 870 | A neighborhood is defined as an instance of a class having operator[] defined. |
philpem@5 | 871 | This particularly includes classical C-array, as well as CImg<T> objects. |
philpem@5 | 872 | |
philpem@5 | 873 | For instance, a 3x3 neighborhood can be defined either as a 'float[9]' or a |
philpem@5 | 874 | 'CImg<float>(3,3)' variable. |
philpem@5 | 875 | |
philpem@5 | 876 | \subsection lo10 Using alternate variable names |
philpem@5 | 877 | |
philpem@5 | 878 | There are also some useful macros that can be used to define variables that |
philpem@5 | 879 | reference the neighborhood elements. There are : |
philpem@5 | 880 | |
philpem@5 | 881 | - \b CImg_2x2(I,type) : Define a 2x2 neighborhood named \c I, of type \c type. |
philpem@5 | 882 | - \b CImg_3x3(I,type) : Define a 3x3 neighborhood named \c I, of type \c type. |
philpem@5 | 883 | - \b CImg_4x4(I,type) : Define a 4x4 neighborhood named \c I, of type \c type. |
philpem@5 | 884 | - \b CImg_5x5(I,type) : Define a 5x5 neighborhood named \c I, of type \c type. |
philpem@5 | 885 | - \b CImg_2x2x2(I,type) : Define a 2x2x2 neighborhood named \c I, of type \c type. |
philpem@5 | 886 | - \b CImg_3x3x3(I,type) : Define a 3x3x3 neighborhood named \c I, of type \c type. |
philpem@5 | 887 | |
philpem@5 | 888 | Actually, \c I is a \e generic \e name for the neighborhood. In fact, these macros declare |
philpem@5 | 889 | a \e set of new variables. |
philpem@5 | 890 | For instance, defining a 3x3 neighborhood \c CImg_3x3(I,float) declares 9 different float variables |
philpem@5 | 891 | \c Ipp,\c Icp,\c Inp,\c Ipc,\c Icc,\c Inc,\c Ipn,\c Icn,\c Inn which correspond to each pixel value of |
philpem@5 | 892 | a 3x3 neighborhood. |
philpem@5 | 893 | Variable indices are \c p,\c c or \c n, and stand respectively for \e 'previous', \e 'current' and \e 'next'. |
philpem@5 | 894 | First indice denotes the \c x-axis, second indice denotes the \c y-axis. |
philpem@5 | 895 | Then, the names of the variables are directly related to the position of the corresponding pixels |
philpem@5 | 896 | in the neighborhood. For 3D neighborhoods, a third indice denotes the \c z-axis. |
philpem@5 | 897 | Then, inside a neighborhood loop, you will have the following equivalence : |
philpem@5 | 898 | - <tt>Ipp = img(x-1,y-1)</tt> |
philpem@5 | 899 | - <tt>Icn = img(x,y+1)</tt> |
philpem@5 | 900 | - <tt>Inp = img(x+1,y-1)</tt> |
philpem@5 | 901 | - <tt>Inpc = img(x+1,y-1,z)</tt> |
philpem@5 | 902 | - <tt>Ippn = img(x-1,y-1,z+1)</tt> |
philpem@5 | 903 | - and so on... |
philpem@5 | 904 | |
philpem@5 | 905 | For bigger neighborhoods, such as 4x4 or 5x5 neighborhoods, two additionnal indices are introduced : |
philpem@5 | 906 | \c a (stands for \e 'after') and \c b (stands for \e 'before'), so that : |
philpem@5 | 907 | - <tt>Ibb = img(x-2,y-2)</tt> |
philpem@5 | 908 | - <tt>Ina = img(x+1,y+2)</tt> |
philpem@5 | 909 | - and so on... |
philpem@5 | 910 | |
philpem@5 | 911 | The value of a neighborhood pixel outside the image range (image border problem) is automatically set to the same |
philpem@5 | 912 | values than the nearest valid pixel in the image (this is also called the \e Neumann \e border \e condition). |
philpem@5 | 913 | |
philpem@5 | 914 | \subsection lo11 Example codes |
philpem@5 | 915 | More than a long discussion, the above example will demonstrate how to compute the gradient norm of a 3D volume |
philpem@5 | 916 | using the \c cimg_for3x3x3() loop macro : |
philpem@5 | 917 | |
philpem@5 | 918 | \code |
philpem@5 | 919 | CImg<float> volume("IRM.hdr"); // Load an IRM volume from an Analyze7.5 file |
philpem@5 | 920 | CImg_3x3x3(I,float); // Define a 3x3x3 neighborhood |
philpem@5 | 921 | CImg<float> gradnorm(volume); // Create an image with same size as 'volume' |
philpem@5 | 922 | cimg_for3x3x3(volume,x,y,z,0,I) { // Loop over the volume, using the neighborhood I |
philpem@5 | 923 | const float ix = 0.5f*(Incc-Ipcc); // Compute the derivative along the x-axis. |
philpem@5 | 924 | const float iy = 0.5f*(Icnc-Icpc); // Compute the derivative along the y-axis. |
philpem@5 | 925 | const float iz = 0.5f*(Iccn-Iccp); // Compute the derivative along the z-axis. |
philpem@5 | 926 | gradnorm(x,y,z) = std::sqrt(ix*ix+iy*iy+iz*iz); // Set the gradient norm in the destination image |
philpem@5 | 927 | } |
philpem@5 | 928 | gradnorm.display("Gradient norm"); |
philpem@5 | 929 | \endcode |
philpem@5 | 930 | |
philpem@5 | 931 | And the following example shows how to deal with neighborhood references to blur a color image by averaging |
philpem@5 | 932 | pixel values on a 5x5 neighborhood. |
philpem@5 | 933 | |
philpem@5 | 934 | \code |
philpem@5 | 935 | CImg<unsigned char> src("image_color.jpg"), dest(src,false), neighbor(5,5); // Image definitions. |
philpem@5 | 936 | typedef unsigned char uchar; // Avoid space in the second parameter of the macro CImg_5x5x1 below. |
philpem@5 | 937 | CImg<> N(5,5); // Define a 5x5 neighborhood as a 5x5 image. |
philpem@5 | 938 | cimg_forV(src,k) // Standard loop on color channels |
philpem@5 | 939 | cimg_for5x5(src,x,y,0,k,N) // 5x5 neighborhood loop. |
philpem@5 | 940 | dest(x,y,k) = N.sum()/(5*5); // Averaging pixels to filter the color image. |
philpem@5 | 941 | CImgList<unsigned char> visu(src,dest); |
philpem@5 | 942 | visu.display("Original + Filtered"); // Display both original and filtered image. |
philpem@5 | 943 | \endcode |
philpem@5 | 944 | |
philpem@5 | 945 | As you can see, explaining the use of the CImg neighborhood macros is actually more difficult than using them ! |
philpem@5 | 946 | |
philpem@5 | 947 | **/ |
philpem@5 | 948 | /*@}*/ |
philpem@5 | 949 | |
philpem@5 | 950 | /*----------------------------------- |
philpem@5 | 951 | |
philpem@5 | 952 | Using display windows |
philpem@5 | 953 | |
philpem@5 | 954 | -------------------------------------*/ |
philpem@5 | 955 | |
philpem@5 | 956 | /** \addtogroup cimg_displays Using Display Windows. */ |
philpem@5 | 957 | /*@{*/ |
philpem@5 | 958 | /** |
philpem@5 | 959 | \page foo_di |
philpem@5 | 960 | |
philpem@5 | 961 | When opening a display window, you can choose the way the pixel values will be normalized |
philpem@5 | 962 | before being displayed on the screen. Screen displays only support color values between [0,255], |
philpem@5 | 963 | and some |
philpem@5 | 964 | |
philpem@5 | 965 | When displaying an image into the display window using CImgDisplay::display(), values of |
philpem@5 | 966 | the image pixels can be eventually linearly normalized between [0,255] for visualization purposes. |
philpem@5 | 967 | This may be useful for instance when displaying \p CImg<double> images with pixel values |
philpem@5 | 968 | between [0,1]. |
philpem@5 | 969 | The normalization behavior depends on the value of \p normalize which can be either \p 0,\p 1 or \p 2 : |
philpem@5 | 970 | - \p 0 : No pixel normalization is performed when displaying an image. This is the fastest |
philpem@5 | 971 | process, but you must be sure your displayed image have pixel values inside the range [0,255]. |
philpem@5 | 972 | - \p 1 : Pixel value normalization is done for each new image display. Image pixels are |
philpem@5 | 973 | not modified themselves, only displayed pixels are normalized. |
philpem@5 | 974 | - \p 2 : Pixel value normalization is done for the first image display, then the |
philpem@5 | 975 | normalization parameters are kept and used for all the next image displays. |
philpem@5 | 976 | |
philpem@5 | 977 | **/ |
philpem@5 | 978 | /*@}*/ |
philpem@5 | 979 | |
philpem@5 | 980 | /*----------------------------------- |
philpem@5 | 981 | |
philpem@5 | 982 | How pixel data are stored |
philpem@5 | 983 | |
philpem@5 | 984 | -------------------------------------*/ |
philpem@5 | 985 | |
philpem@5 | 986 | /** \addtogroup cimg_storage How pixel data are stored with CImg. */ |
philpem@5 | 987 | /*@{*/ |
philpem@5 | 988 | /** |
philpem@5 | 989 | \page foo_store |
philpem@5 | 990 | |
philpem@5 | 991 | First, CImg<T> are *very* basic structures, which means that there are no memory tricks, weird memory alignments or |
philpem@5 | 992 | disk caches used to store pixel data of images. When an image is instanced, all its pixel values are stored in memory at |
philpem@5 | 993 | the same time (yes, you should avoid working with huge images when dealing with CImg, if you have only 64kb of RAM). |
philpem@5 | 994 | |
philpem@5 | 995 | A CImg<T> is basically a 4th-dimensional array (width,height,depth,dim), and its pixel data are stored linearly in a single |
philpem@5 | 996 | memory buffer of general size (width*height*depth*dim). Nothing more, nothing less. The address of this memory buffer can be |
philpem@5 | 997 | retrieved by the function CImg<T>::ptr(). |
philpem@5 | 998 | As each image value is stored as a type T (T being known by the programmer of course), this pointer is a 'T*', or a 'const T*' if your image is 'const'. |
philpem@5 | 999 | so, 'T *ptr = img.ptr()' gives you the pointer to the first value of the image 'img'. The overall size of the used memory for one |
philpem@5 | 1000 | instance image (in bytes) is then 'width*height*depth*dim*sizeof(T)'. |
philpem@5 | 1001 | |
philpem@5 | 1002 | Now, the ordering of the pixel values in this buffer follows these rules : |
philpem@5 | 1003 | The values are *not* interleaved, and are ordered first along the X,Y,Z and V axis respectively (corresponding to the width,height,depth,dim dimensions), |
philpem@5 | 1004 | starting from the upper-left pixel to the bottom-right pixel of the instane image, with a classical scanline run. |
philpem@5 | 1005 | |
philpem@5 | 1006 | So, a color image with dim=3 and depth=1, will be stored in memory as : |
philpem@5 | 1007 | |
philpem@5 | 1008 | R1R2R3R4R5R6......G1G2G3G4G5G6.......B1B2B3B4B5B6.... (i.e following a 'planar' structure) |
philpem@5 | 1009 | |
philpem@5 | 1010 | and *not* as R1G1B1R2G2B2R3G3B3... (interleaved channels), |
philpem@5 | 1011 | where R1 = img(0,0,0,0) is the first upper-left pixel of the red component of the image, |
philpem@5 | 1012 | R2 is img(1,0,0,0), G1 = img(0,0,0,1), G2 = img(1,0,0,1), B1 = img(0,0,0,2), and so on... |
philpem@5 | 1013 | |
philpem@5 | 1014 | Another example, a (1x5x1x1) CImg<T> (column vector A) will be stored as : A1A2A3A4A5 |
philpem@5 | 1015 | where A1 = img(0,0), A2 = img(0,1), ... , A5 = img(0,4). |
philpem@5 | 1016 | |
philpem@5 | 1017 | As you see, it is *very* simple and intuitive : no interleaving, no padding, just simple. |
philpem@5 | 1018 | This is cool not only because it is simple, but this has in fact a number of interesting properties. For instance, a 2D color image |
philpem@5 | 1019 | is stored in memory exactly as a 3D scalar image having a depth=3, meaning that when you are dealing with 2D color images, you can write 'img(x,y,k)' |
philpem@5 | 1020 | instead of 'img(x,y,0,k)' to access the kth channel of the (x,y) pixel. More generally, if you have one dimension that is 1 in |
philpem@5 | 1021 | your image, you can just skip it in the call to the operator(). Similarly, values of a column vector stored as an image with |
philpem@5 | 1022 | width=depth=dim=1 can be accessed by 'img(y)' instead of 'img(0,y)'. This is very convenient. |
philpem@5 | 1023 | |
philpem@5 | 1024 | Another cool thing is that it allows you to work easily with 'shared' images. A shared image is a CImg<T> instance that shares |
philpem@5 | 1025 | its memory with another one (the 'base' image). Destroying a shared image does nothing in fact. Shared images is a convenient |
philpem@5 | 1026 | way of modifying only *portions* (consecutive in memory) of an image. For instance, if 'img' is a 2D color image, you can write : |
philpem@5 | 1027 | |
philpem@5 | 1028 | img.get_shared_channel(0).blur(2); |
philpem@5 | 1029 | img.get_shared_channels(1,2).mirror('x'); |
philpem@5 | 1030 | |
philpem@5 | 1031 | which just blur the red channel of the image, and mirror the two others along the X-axis. |
philpem@5 | 1032 | This is possible since channels of an image are not interleaved but are stored as different consecutive planes in memory, so you see that constructing a shared image is possible (and trivial). |
philpem@5 | 1033 | |
philpem@5 | 1034 | **/ |
philpem@5 | 1035 | /*@}*/ |
philpem@5 | 1036 | |
philpem@5 | 1037 | /*----------------------------------- |
philpem@5 | 1038 | |
philpem@5 | 1039 | Files IO |
philpem@5 | 1040 | |
philpem@5 | 1041 | -------------------------------------*/ |
philpem@5 | 1042 | |
philpem@5 | 1043 | /** \addtogroup cimg_files_io Files IO in CImg. */ |
philpem@5 | 1044 | /*@{*/ |
philpem@5 | 1045 | /** |
philpem@5 | 1046 | \page foo_fi |
philpem@5 | 1047 | |
philpem@5 | 1048 | The %CImg Library can NATIVELY handle the following file formats : |
philpem@5 | 1049 | - RAW : consists in a very simple header (in ascii), then the image data. |
philpem@5 | 1050 | - ASC (Ascii) |
philpem@5 | 1051 | - HDR (Analyze 7.5) |
philpem@5 | 1052 | - INR (Inrimage) |
philpem@5 | 1053 | - PPM/PGM (Portable Pixmap) |
philpem@5 | 1054 | - BMP (uncompressed) |
philpem@5 | 1055 | - PAN (Pandore-5) |
philpem@5 | 1056 | - DLM (Matlab ASCII) |
philpem@5 | 1057 | |
philpem@5 | 1058 | If ImageMagick is installed, The %CImg Library can save image in formats handled by ImageMagick : JPG, GIF, PNG, TIF,... |
philpem@5 | 1059 | |
philpem@5 | 1060 | **/ |
philpem@5 | 1061 | /*@}*/ |
philpem@5 | 1062 | |
philpem@5 | 1063 | /*----------------------------------- |
philpem@5 | 1064 | |
philpem@5 | 1065 | Retrieving command line arguments |
philpem@5 | 1066 | |
philpem@5 | 1067 | -------------------------------------*/ |
philpem@5 | 1068 | |
philpem@5 | 1069 | /** \addtogroup cimg_options Retrieving Command Line Arguments. */ |
philpem@5 | 1070 | /*@{*/ |
philpem@5 | 1071 | /** |
philpem@5 | 1072 | \page foo_so |
philpem@5 | 1073 | |
philpem@5 | 1074 | The CImg library offers facilities to retrieve command line arguments in a console-based |
philpem@5 | 1075 | program, as it is a commonly needed operation. |
philpem@5 | 1076 | Three macros \c cimg_usage(), \c cimg_help() and \c cimg_option() are defined for this purpose. |
philpem@5 | 1077 | Using these macros allows to easily retrieve options values from the command line. |
philpem@5 | 1078 | Invoking the compiled executable with the option \c -h or \c --help will |
philpem@5 | 1079 | automatically display the program usage, followed by the list of requested options. |
philpem@5 | 1080 | |
philpem@5 | 1081 | \section so1 The cimg_usage() macro |
philpem@5 | 1082 | |
philpem@5 | 1083 | The macro \c cimg_usage(usage) may be used to describe the program goal and usage. |
philpem@5 | 1084 | It is generally inserted one time after the <tt>int main(int argc,char **argv)</tt> definition. |
philpem@5 | 1085 | |
philpem@5 | 1086 | \param usage : A string describing the program goal and usage. |
philpem@5 | 1087 | \pre The function where \c cimg_usage() is used must have correctly defined \c argc and \c argv variables. |
philpem@5 | 1088 | |
philpem@5 | 1089 | \section so1_5 The cimg_help() macro |
philpem@5 | 1090 | |
philpem@5 | 1091 | The macro \c cimg_help(str) will display the string \c str only if the \c -help or \c --help option |
philpem@5 | 1092 | are invoked when running the programm. |
philpem@5 | 1093 | |
philpem@5 | 1094 | \section so2 The cimg_option() macro |
philpem@5 | 1095 | |
philpem@5 | 1096 | The macro \c cimg_option(name,default,usage) may be used to retrieve an option value from the command line. |
philpem@5 | 1097 | |
philpem@5 | 1098 | \param name : The name of the option to be retrieved from the command line. |
philpem@5 | 1099 | \param default : The default value returned by the macro if no options \p name has been specified when running the program. |
philpem@5 | 1100 | \param usage : A brief explanation of the option. If \c usage==0, the option won't appear on the option list |
philpem@5 | 1101 | when invoking the executable with options \c -h or \c --help (hidden option). |
philpem@5 | 1102 | |
philpem@5 | 1103 | \return \c cimg_option() returns an object that has the \e same \e type than the default value \c default. |
philpem@5 | 1104 | The return value is equal to the one specified on the command line. If no such option have been specified, |
philpem@5 | 1105 | the return value is equal to the default value \c default. |
philpem@5 | 1106 | Warning, this can be confusing in some situations (look at the end of the next section). |
philpem@5 | 1107 | \pre The function where \c cimg_option() is used must have correctly defined \c argc and \c argv variables. |
philpem@5 | 1108 | |
philpem@5 | 1109 | \section so3 Example of use |
philpem@5 | 1110 | |
philpem@5 | 1111 | The code below uses the macros \c cimg_usage() and \c cimg_option(). |
philpem@5 | 1112 | It loads an image, smoothes it an quantifies it with a specified number of values. |
philpem@5 | 1113 | \code |
philpem@5 | 1114 | #include "CImg.h" |
philpem@5 | 1115 | using namespace cimg_library; |
philpem@5 | 1116 | int main(int argc,char **argv) { |
philpem@5 | 1117 | cimg_usage("Retrieve command line arguments"); |
philpem@5 | 1118 | const char* filename = cimg_option("-i","image.gif","Input image file"); |
philpem@5 | 1119 | const char* output = cimg_option("-o",(char*)0,"Output image file"); |
philpem@5 | 1120 | const double sigma = cimg_option("-s",1.0,"Standard variation of the gaussian smoothing"); |
philpem@5 | 1121 | const int nblevels = cimg_option("-n",16,"Number of quantification levels"); |
philpem@5 | 1122 | const bool hidden = cimg_option("-hidden",false,0); // This is a hidden option |
philpem@5 | 1123 | |
philpem@5 | 1124 | CImg<unsigned char> img(filename); |
philpem@5 | 1125 | img.blur(sigma).quantize(nblevels); |
philpem@5 | 1126 | if (output) img.save(output); else img.display("Output image"); |
philpem@5 | 1127 | if (hidden) std::fprintf(stderr,"You found me !\n"); |
philpem@5 | 1128 | return 0; |
philpem@5 | 1129 | } |
philpem@5 | 1130 | \endcode |
philpem@5 | 1131 | |
philpem@5 | 1132 | Invoking the corresponding executable with <tt>test -h -hidden -n 20 -i foo.jpg</tt> will display : |
philpem@5 | 1133 | \verbatim |
philpem@5 | 1134 | ./test -h -hidden -n 20 -i foo.jpg |
philpem@5 | 1135 | |
philpem@5 | 1136 | test : Retrieve command line arguments (Oct 16 2004, 12:34:26) |
philpem@5 | 1137 | |
philpem@5 | 1138 | -i = foo.jpg : Input image file |
philpem@5 | 1139 | -o = 0 : Output image file |
philpem@5 | 1140 | -s = 1 : Standard variation of the gaussian smoothing |
philpem@5 | 1141 | -n = 20 : Number of quantification levels |
philpem@5 | 1142 | |
philpem@5 | 1143 | You found me ! |
philpem@5 | 1144 | \endverbatim |
philpem@5 | 1145 | |
philpem@5 | 1146 | \warning As the type of object returned by the macro \c cimg_option(option,default,usage) |
philpem@5 | 1147 | is defined by the type of \c default, undesired casts may appear when writting code such as : |
philpem@5 | 1148 | \code |
philpem@5 | 1149 | const double sigma = cimg_option("-val",0,"A floating point value"); |
philpem@5 | 1150 | \endcode |
philpem@5 | 1151 | In this case, \c sigma will always be equal to an integer (since the default value \c 0 is an integer). |
philpem@5 | 1152 | When passing a float value on the command line, a \e float \e to \e integer cast is then done, |
philpem@5 | 1153 | truncating the given parameter to an integer value (this is surely not a desired behavior). |
philpem@5 | 1154 | You must specify <tt>0.0</tt> as the default value in this case. |
philpem@5 | 1155 | |
philpem@5 | 1156 | \section so4 How to learn more about command line options ? |
philpem@5 | 1157 | You should take a look at the examples <tt>examples/gmic.cpp</tt> provided in the %CImg Library package. |
philpem@5 | 1158 | This is a command line based image converter which intensively uses the \c cimg_option() and \c cimg_usage() |
philpem@5 | 1159 | macros to retrieve command line parameters. |
philpem@5 | 1160 | **/ |
philpem@5 | 1161 | /*@}*/ |
philpem@5 | 1162 |