Changes for FXImage

Image Data Representation

In FOX 1.0, all of the APIs concerned with transferring icon and image pixel data worked with arrays of bytes, represented as arrays of FXuchar values. For example, the fxloadGIF() function loaded a GIF image from a previously opened FXStream and returned an array of bytes representing the image's pixel data:

FXuchar *data;
FXColor transp;
FXint width, height;
if (fxloadGIF(store, data, transp, width, height)) {
    ...
}

A problem with this approach was that the size of the data array depends not only on the image size (i.e. its width and height) but the number of color channels in the image, which varies from image format to image format.

In order to make these APIs more consistent and easier to use, image objects now always have an alpha channel. These APIs now work exclusively with arrays of FXColor values, e.g.

FXColor *data;
FXint width, height;
if (fxloadGIF(store, data, width, height)) {
    ...
}

The new hasAlpha() member function scans the image pixel data and returns FALSE if the image is completely opaque, i.e. it has some alpha value less than 255.

Client-Side Pixel Buffer

When you call restore() to retrieve the pixels from the server-side image, FXImage now only allocates a client-side pixel buffer if it needs one (i.e. if one doesn't exist already). In FOX 1.0, calling restore() would always result in the FXImage taking "ownership" of the client-side pixel buffer; in other words, it would allocate its own private buffer of the correct size and use that to store the newly acquired pixel data. Now, it can store the pixel data in the buffer that you originally passed in.

Calling the new release() member function on an FXImage object will cause it to release (i.e. "forget about") its client-side pixel buffer. If the FXImage object owned that pixel buffer it will of course be deleted first.

The savePixels() and loadPixels() member functions now return FXbool (instead of void).

New and Changed Image Manipulation APIs

The scale() member function for FXImage now accepts an optional third argument to specify the quality of the scaling algorithm used. By default, the scale() function now uses a much faster (but lower quality) nearest-neighbor algorithm for scaling the image to its new size. To use the previous scaling algorithm from FOX 1.0, you should pass in a value of 1 as the third argument to scale().

In addition to this change, several new image manipulation APIs have been added to the FXImage class.

The fill() member function simply fills an image with a uniform color. The hgradient() and vgradient() member functions fill an image with a horizontal (or vertical) gradient using two colors. The gradient() member function fills an image with a bilinear gradient using four different colors.

The blend() member function is a little different in that it "blends" the image over a uniform color that you specify. Note that blend() only has an effect if the image data contains an alpha (transparency) channel.

The fade() member function fades an image to a certain color by a certain factor. The factor is some integer value between 0 and 255 inclusive, where a factor of 255 indicates no fading and a factor of zero indicates that the image is completely faded to the fade color.

Figure 1. Image with no fading (factor = 255)

Image with no fading (factor = 255)

Figure 2. Image with fading (factor = 192)

Image with fading (factor = 192)

Figure 3. Image with fading (factor = 128)

Image with fading (factor = 128)

Figure 4. Image with fading (factor = 64)

Image with fading (factor = 64)

The xshear() and yshear() member functions perform a shear operation on the image, turning it into a parallelogram. For each of these functions, the first argument is an integer value indicating how far to shift the image in the horizontal (or vertical direction). The number of pixels that the image is shifted is 256 times this parameter. The second argument is the color used to fill the area outside the image and defaults to zero (i.e. transparent black).

Postscript Output

The new fxsavePS() function can be used to save image data to a PostScript file. For example,

void saveThisImage(const FXImage *image, const FXString& filename) {
    FXFileStream store;
    if (store.open(filename, FXStreamSave)) {
        fxsavePS(store, image->getData(), image->getWidth(), image->getHeight());
        store.close();
    }
}

The resulting PostScript image is formatted to the largest size that fits within the specified paper size and margins. By default, the paper width and height are assumed to be 612 points and 792 points, respectively (with margins of 35 points). This corresponds to a paper size of 8.5 by 11 inches (with approximately 0.5 inch margins on each side). To change these values, pass in the appropriate sizes as the fifth, sixth and seventh arguments of fxsavePS(), e.g.

void saveThisImage(const FXImage *image, const FXString& filename,
                   FXint paperWidthInPoints, FXint paperHeightInPoints, FXint marginInPoints) {
    FXFileStream store;
    if (store.open(filename, FXStreamSave)) {
        fxsavePS(store, image->getData(), image->getWidth(), image->getHeight(),
                 paperWidthInPoints, paperHeightInPoints, marginInPoints);
        store.close();
    }
}

Finally, both color and grayscale images are supported. By default, fxsavePS() will save the image as a color image, but you can change this by passing in FALSE as the eighth argument to fxsavePS().