Programming with wxImage

team bbl


Programming with wxImage

Use wxImage when you need to manipulate images in a platform-independent manner, or as an intermediate step for loading or saving image files. Images are stored using a byte per pixel for each of the red, green, and blue channels, plus a further byte per pixel if an alpha channel is present.

The major wxImage functions are listed in Table 10-6.

Table 10-6. wxImage Functions

wxImage

An image can be created given a width and height, another image, XPM data, raw data (char[]) and optional alpha data, a file name and type, or an input stream.

ConvertAlphaToMask

Converts the alpha channel (if any) to a mask.

ConvertToMono

Converts to a new monochrome image.

Copy

Returns an identical copy without using reference counting.

Create

Creates an image of a given size, optionally initializing it from data.

Destroy

Destroys the internal data if no other object is using it.

GeTData, SetData

Gets and sets its pointer to internal data (unsigned char*).

GetImageCount

Returns the number of images in a file or stream.

GetOption, GetOptionInt, SetOption, HasOption

Gets, sets, and tests for the presence of options.

GetSubImage

Returns an area of the image as a new image.

GetWidth, GetHeight

Returns the image size.

Getred, GetGreen, GetBlue, SetRGB, GetAlpha, SetAlpha

Gets and sets the red, blue, green, and alpha value for a pixel.

HasMask, GetMaskRed, GetMaskGreen, GetMaskBlue, SetMaskColour

Functions for testing for the presence of a mask and setting and getting the mask color.

LoadFile, SaveFile

Files can be loaded and saved using various formats.

Mirror

Mirrors the image in either orientation, returning a new image.

Ok

Returns true if the image is initialized.

Paste

Pastes an image into this image at a given position.

Rotate, Rotate90

Rotates the image, returning a new image.

SetMaskFromImage

Sets a mask, specifying an image and color to use for the transparent area.

Scale, Rescale

Scales to a new image or scales in place.


Loading and Saving Images

wxImage can load and save in a variety of formats, using image handlers that plug into wxImage and provide extensibility. The wxImage file-handling capabilities are used as a fallback for the other bitmap classes for when they don't provide appropriate native implementations.

Table 10-7 shows the image handlers available on all platforms supported by wxWidgets. wxBMPHandler is always installed by default. To use other image formats, install the appropriate handler with wxImage::AddHandler or wxInitAllImageHandlers.

If you will be using a specific set of formats, you might typically have these in your wxApp::OnInit function:

 #include "wx/image.h" wxImage::AddHandler( new wxPNGHandler ); wxImage::AddHandler( new wxJPEGHandler ); wxImage::AddHandler( new wxGIFHandler ); wxImage::AddHandler( new wxXPMHandler ); 

Alternatively, you can just call:

 wxInitAllImageHandlers(); 

Here are some different ways of loading and saving images from files and streams. Note that when loading files, you should normally use absolute paths instead of depending on the setting of the current directory.

 // Load image using constructor and specific type wxImage image(wxT("image.png"), wxBITMAP_TYPE_PNG); if (image.Ok()) {     ... } // Leave wxImage to work out the image type wxImage image(wxT("image.png")); // Two-step loading wxImage image; if (image.LoadFile(wxT("image.png"))) {     ... } // Two-step loading with an index into a multi-image file: // load image number 2 if available wxImage image; int imageCount = wxImage::GetImageCount(wxT("image.tif")); if (imageCount > 2)     image.LoadFile(wxT("image.tif"), wxBITMAP_TYPE_TIFF, 2); // Load from a stream wxFileInputStream stream(wxT("image.tif")); wxImage image; image.LoadFile(stream, wxBITMAP_TYPE_TIF); // Save to a file image.SaveFile(wxT("image.png")), wxBITMAP_TYPE_PNG); // Save to a stream wxFileOutputStream stream(wxT("image.tif")); image.SaveFile(stream, wxBITMAP_TYPE_TIF); 

Images will be saved as 24-bit files, with the exception of XPM and PCX formats, whose handlers will count the number of colors and save with the appropriate depth. JPEG has a quality setting that you can set before saving the file. The setting is a number between 0 and 100, where 0 is poor quality and high compression, and 100 is high quality and poor compression.

 // Save with reasonable quality and compression image.SetOption(wxIMAGE_OPTION_QUALITY, 80); image.SaveFile(wxT("picture.jpg"), wxBITMAP_TYPE_JPEG); 

You also might want to use wxImage::SetOption when saving an XPM to a streambecause no file name is passed, the handler won't know what name to use for the C variable that is part of the XPM data. For example:

 // Save XPM to a stream image.SetOption(wxIMAGE_OPTION_FILENAME, wxT("myimage")); image.SaveFile(stream, wxBITMAP_TYPE_XPM); 

Note that it will append _xpm to the file name that you specify.

Transparency

There are two ways of using transparency with wxImage: masks and alpha channels. One color value of the image may be used as a mask color, which will lead to the automatic creation of a wxMask object when converted to a wxBitmap.

wxImage also supports alpha channel data. In addition to a byte for the red, green, and blue color components for each pixel, it also stores a byte representing the pixel opacity. The alpha value of 0 corresponds to a transparent pixel (zero opacity), and the value of 255 means that the pixel is 100% opaque.

Not all images have an alpha channel, and before using GetAlpha, you should determine whether this image contains alpha values with HasAlpha. Currently, only images loaded from PNG files or assigned an alpha channel with SetAlpha can have an alpha channel. Saving images with an alpha channel is not yet supported. Drawing with the alpha channel is supported by converting the image to a wxBitmap and calling wxDC::DrawBitmap or wxDC::Blit.

The following code shows how to create a wxImage with a mask. The image will be blue, containing a transparent rectangle.

 // Create masked image // First, draw on a wxBitmap wxBitmap bitmap(400, 400); wxMemoryDC dc; dc.SelectObject(bitmap); dc.SetBackground(*wxBLUE_BRUSH); dc.Clear(); dc.SetPen(*wxRED_PEN); dc.SetBrush(*wxRED_BRUSH); dc.DrawRectangle(50, 50, 200, 200); dc.SelectObject(wxNullBitmap); // Convert the bitmap to an image wxImage image = bitmap.ConvertToImage(); // Set the mask color to red image.SetMaskColour(255, 0, 0); 

Another method is to create the mask from another image. In the following example, image.bmp contains the main image, and mask.bmp has black pixels where the transparent area should be.

 // Load image and its mask wxImage image(wxT("image.bmp"), wxBITMAP_TYPE_BMP); wxImage maskImage(wxT("mask.bmp"), wxBITMAP_TYPE_BMP); // Specify black for the transparent area image.SetMaskFromImage(maskImage, 0, 0, 0); 

If you have loaded a transparent image from disk, you can check for transparency and retrieve the mask color:

 // Load transparent image wxImage image(wxT("image.png"), wxBITMAP_TYPE_PNG); // Retrieve the mask if (image.HasMask()) {     wxColour maskColour(image.GetMaskRed(),     image.GetMaskGreen(),     image.GetMaskBlue()); } 

Transformations

wxImage supports scaling, rotating, and mirroring transformations. Here are some examples:

 // Scale an image to 200x200 and assign to another image. // image1 remains unmodified. wxImage image2 = image1.Scale(200, 200); // Rescale an image to 200x200 image1.Rescale(200, 200); // Rotate by a specified number of radians. // image1 remains unmodified. wxImage image2 = image1.Rotate(0.5); // Rotate by 90 degrees in the clockwise direction. // image1 remains unmodified. wxImage image2 = image1.Rotate90(true); // Mirror the image horizontally. // image1 remains unmodified. wxImage image2 = image1.Mirror(true); 

Color Reduction

If you need to reduce the number of colors in an image, you can use the static functions of the wxQuantize class. The main function of interest, Quantize, takes an input image, an output image, an optional wxPalette** to get a new palette containing the reduced colors, and the desired number of colors. You can also pass an unsigned char** variable to retrieve an 8-bit representation of the output image and a style for further control of what is returned; see the reference manual for more on these.

The following code shows how to reduce an image to a maximum of 256 colors:

 #include "wx/image.h" #include "wx/quantize.h" wxImage image(wxT("image.png")); int maxColorCount = 256; int colors = image.CountColours(); wxPalette* palette = NULL; if (colors > maxColorCount ) {     wxImage reducedImage;     if (wxQuantize::Quantize(image, reducedImage,                                & palette, maxColorCount))     {         colors = reducedImage.CountColours();         image = reducedImage;     } } 

An image can have a wxPalette associated with it, for example when the image has been loaded from a GIF file. However, the image is still in RGB format, and the palette merely indicates the original mapping between index values and RGB values. wxPalette can also be set for a wxImage so that SaveFile can save it in a format that has a limited number of colors. For example, the Windows BMP handler determines whether the wxBMP_8BPP_PALETTE image option is set and, if so, uses the image's palette; if the wxBMP_8BPP option is set, it does its own quantization. Some handlers always do their own color reduction, such as PCX, unless they find that the number of unique colors is already low enough.

For more on wxPalette, please see "wxPalette" in Chapter 5.

Manipulating wxImage Data Directly

You can access image data with Getdata for faster manipulation than using GeTRed, GetBlue, GetGreen, and SetRGB. Here's an example of converting a color image to a grayscale:

 void wxImage::ConvertToGrayScale(wxImage& image) {     double red2Gray   = 0.297;     double green2Gray = 0.589;     double blue2Gray  = 0.114;     int w = image.GetWidth(), h = image.GetHeight();     unsigned char *data = image.GetData();     int x,y;     for (y = 0; y < h; y++)         for (x = 0; x < w; x++)         {             long pos = (y * w + x) * 3;             char g = (char) (data[pos]*red2Gray +                               data[pos+1]*green2Gray +                               data[pos+2]*blue2Gray);             data[pos] = data[pos+1] = data[pos+2] = g;         } } 

    team bbl



    Cross-Platform GUI Programming with wxWidgets
    Cross-Platform GUI Programming with wxWidgets
    ISBN: 0131473816
    EAN: 2147483647
    Year: 2005
    Pages: 262

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net