Next: Supported Image Formats, Previous: Supported image types, Up: Part VI Images [Contents][Index]
With the basic fields in the image structure and image types explained, we’re now in a position to tackle the problem of creating images on the fly. The data may have come from some simulations or some other means, the task now is to create an image from the data and try to display/visualize it.
The first task involved in creating an image is to create an image structure that is properly initialized. To this end, the following routine is available
FL_IMAGE *flimage_alloc(void);
The function returns a pointer to a piece of dynamically allocated memory that’s properly initialized.
The task next is to put the existing data into the structure. This
involves several steps. The first step is to figure out what type of
image to create. For scalar data, there are two logical choices,
either a gray-scale intensity image or a color index image with the
data being interpreted as indices into some lookup table. Both of
these may be useful. Gray-scale imagse are straight forward to create
and the meaning of the pixel values is well defined and understood. On
the other hand with color-mapped image you can selectively enhance the
data range you want to visualize by choosing appropriate color-maps.
For vector data, RGB image probably makes most sense. In any case it’s
strictly application’s decision. All that is needed to make it work
with Forms Library is to set the image->type
field to a valid
value. Of course the image dimension (width and height) also needs to
be set. Once this is done, we need to copy the data into the image
structure.
Before we copy the data we create the destination storage using one of the following routines
void *fl_get_matrix(int nrows, int ncols, unsigned int elem_size); int flimage_getmem(FL_IMAGE *image);
The fl_get_matrix()
function creates a 2-dimensional
array of entities of size elem_size
. The array is of
nrows
by ncols
in size. The 2D array can be passed as a
pointer to pointer and indexed as a real 2D arrays. The
flimage_getmem()
routine allocates the proper amount of
memory appropriate for the image type, including colormaps when
needed.
After the destination storage is allocated, copying the data into it is simple
image->type = FL_IMAGE_GRAY; image->w = data_columns; image->h = data_row; flimage_getmem(image); /* or you can use the instead im->gray = fl_get_matrix(im->h, im->w, sizeof **im->gray); */ for (row = 0; row < image->h; row++) for (col = 0; col < image->w; col++) image->gray[row][col] = data_at_row_and_col;
Of course, if data is stored row-by-row, a memcpy(3)
instead of
a loop over columns may be more efficient. Also if your data are
stored in a single array, fl_make_matrix()
might be a lot
faster as it does not copy the data.
If the created image is a color index image, in addition to copying
the data to image->ci
, you also need to set the lookup table
length image->map_len
, which should reflect the dynamic range
of the data:
image->type = FL_IMAGE_CI; image->w = A; image->h = B; image->map_len = X; flimage_getmem(image); /* this will allocate ci and lut */ for (row = 0; row < image->h; row++) for (col = 0; col < image->w; col++) image->ci[row][col] = data; for (i = 0; i < image->map_len; i++) { image->red_lut[i] = some_value_less_than_FL_PCMAX; image->green_lut[i] = some_value_less_than_FL_PCMAX; image->blue_lut[i] = some_value_less_than_FL_PCMAX; }
If the type is FL_IMAGE_GRAY16
, you also need to set
image->gray_maxval
to the maximum value in the data.
Now we’re ready to display the image
flimage_display(image, win);
As mentioned before, the display routine may create a buffered, display hardware specific and potentially lower-resolution image than the original image. If for any reason, you need to modify the image, either the pixels or the lookup tables, you need to inform the library to invalidate the buffered image:
image->modified = 1;
Next: Supported Image Formats, Previous: Supported image types, Up: Part VI Images [Contents][Index]