MIN-Faculty
Department of Informatics
Scene analysis and visualization (SAV)
Tutorial navigation (Using the VIGRA under Windows with Dev-C++)
< 1 Installation Table of contents

 

2  The first VIGRA program: converter

This part of the tutorial assumes, that you already installed all needed packages. If this is not the case, plase visit the first part of this tutorial.
We will write our first C++ program with VIGRA support right now. The program should be a simple converter of one image filename and filetype to another. A possible program call could look like this:

> converter lenna_rgb.bmp lenna_rgb.jpg

which qould cause a filetype-conversion from Bitmap (*.bmp) to JPEG (*.jpg) of the image lenna_rgb.bmp.
Let us first create a new project in Dev-C++. Therefore, you may create a folder named "lesson1" anywahere on your harddisk. Afterwards start Dev-C++ and select the menu entry "File->New->Project" to create a new project (see here). The project should be of type "empty project" and you should give it a proper name (e.g. converter) like you see here. Now Dev-C++ will ask you for a folder to store your project. You can navigate to the newly created folder and selecta proper project filename (e.g. converter.dev).
We just need two more things to starts:

  • We have to change some linker settings under "Project->Project Options" (see here) because we want to link the VIGRA-Import/Export library with our project. BEause of this, we select the tab "Parameters" and add the vigraimpex library using "Add Library or Object". You will find the library under "Dev-Cpp\lib\libvigraimpex.a". After successful selection, your window should look like this image and you should save the new settings by clicking "OK". Now, we have fulfilled all requirements for the use of the VIGRA inside Dev-C++ (the include paths have already been set correcly by the installation of the VIGRA package after step 1).
  • To add some functionality to our project, we have to add some source code to our project. This can be done with the menu entry "File->New->Source File". We do so, and add one file "converter.cxx" to our project.

Now, we can start with the source code of our example:

01: #include <iostream>
02: #include "vigra/stdimage.hxx"
03: #include "vigra/impex.hxx"
04:
05: using namespace vigra;
06:
07:

The first three lines include some functions, that we want to use in qur example: The include "iostream"gives us components for the stream-based in- and output to the console. The other includes are VIGRA-includes. The first of them ist needed for representation of an image and the second one is needed for the import-export facilities of the vigra.
Die follwing line 05 ensures, that we have access to the VIGRA-namespace without having to type vigra:: each time we want to access vigra functions and or objects. (e.g. it is now sufficient to write BasicImage<T> instead of vigra::BasicImage<T>).

08: int main(int argc, char ** argv)
09: {
10:    if(argc != 3)
11:    {
12:        std::cout << "Usage: " << argv[0] << " infile outfile" << std::endl;
13:        std::cout << "(supported formats: " << impexListFormats() << ")" << std::endl;
14:       return 1;
15:    }
16:

The main function is called at each execution ofthe program. You will get access to the program parameters via the argv array of char* and argc tells how how many arguments have been passed to your program. argv[0] is always equal to the name of the executed binary. As our converter should handle two given parameters, we first check if there ist a total amount of three parameters. If the parameter count differs from three, we return an usage informationa message to tell the user how to execute the program. At this point the function "impexListFormats()" returns all available import/export-formats that are supported by the current vigra installation. Finally we return the integer "1" to tell the shell that this program caused an error. Otherwise we would have returned "0".

17:    try
18:    {
19:        ImageImportInfo info(argv[1]);
20:
21:        if(info.isGrayscale())
22:        {
23:            BImage in(info.width(), info.height());
24:
25:            importImage(info, destImage(in));
26:            exportImage(srcImageRange(in), ImageExportInfo(argv[2]));
27:        }

The "try" at line 17 enables the error handling for our example. This is neccessary each time we access external devices that be in an error state. In this example the given file may not exist or may be currupt. After this, we create a new VIGRA-ImageImportInfo using the first given parameter ("argv[1]"). This ImageImfortInfo collects informations about the image, e.g. size of the image, colorspace etc. One of these informations is if the image is an grayvalue image or if it is a color image. Color images were represented differently by the VIGRA and have therefore be handled separately by our program. But let us first care about the grayvalue case.
In line 23 we create a vigra::BasicImage of type BYTE (shortform BImage) named "in" of proper size, Note that we can get the size of the image, that we want to load from the ImageImportInfo even before loading the image.
Finally we call importImage to import the image to our image "in" and exportImage to export it into the given second parameter "argv[2]").

28:        else
29:        {
30:            vigra::BRGBImage in(info.width(), info.height());
31:
32:            importImage(info, destImage(in));
33:            exportImage(srcImageRange(in), vigra::ImageExportInfo(argv[2]));
34:        }
35:    }
36:    catch (vigra::StdException & e)
37:    {
38:        std::cout << e.what() << std::endl;
39:        return 1;
40:    }
41:    return 0;
42:}

We find the import / export of RGB images in the above else-block. Note that RGB-images are represented by BasicImages of type RGBValue. If we assume one byte per channel we can use the shorter form: BRGBImage which is equivalent to Basicimage<RGBValue<BYTE> >.
At the end, we catch any thrown errors and print them out at the console.If no errors have occured, we return a "0" indicating the success.
That is all we need for our first example, now set the calling parameters "Excecute->Parameters" to exisiting images and build/start the program using "Excecute->Compile&Run"!