|
Volume Number: 13 (1997)
Issue Number: 10
Column Tag: Tips & Tidbits
Tips & Tidbits
By Steve Sisak
Colorizing Pixmaps in PICT Images
In a progect I am working on, I have a set of PICT resources that are used to draw a background for my app's user interface. The PICT's are used to represent modular panels and the the user is allowed to colorize these backing panels. The code to colorize the backing pixmaps is relatively simple, but the Mac OS provides a gotcha.
The basic technique uses CopyBits to colorize the pixel data by setting the foreground and background colors of the destination port. The problem is that if you set the colors in the port before playing back the picture, the DrawPicture routine undoes your work for you and the pixel data from the PICT is not colorized. The following code uses the QuickDraw bottlenecks to circumvent the problem. To use it, call DrawColorizedPicture instead of DrawPicture and add the colorization colors you want as parameters.
For example:
RGBColor red = {0xffff,0,0}; RGBColor black = {0,0,0}; Rect bounds; // turn a grayscale image into a red-scale image: bounds = (**aPicHandle).bounds; DrawColorizedPicture(aPicHandle, &bounds, &black, &red);
Here is the code that implements DrawColorizedPicture:
// Define some global variables to pass the colorization information RGBColor gFGColor; RGBColor gBGColor; // here is the overriden bottleneck (myQDBitsProcPtr). // it sets up the color environment before actually coping the pixmap pascal void myQDBitsProcPtr(BitMap *srcBits, Rect *srcRect, Rect *dstRect, short mode, RgnHandle maskRgn) { GrafPtr curPort; RGBColor saveFG; RGBColor saveBG; GetPort(&curPort); // get the context // save the fore- and background colors saveFG = ((CGrafPort*)curPort)->rgbFgColor; saveBG = ((CGrafPort*)curPort)->rgbBkColor; RGBForeColor(&gFGColor); // set the foreground color RGBBackColor(&gBGColor); // set the background color // call the standard routine StdBits(srcBits, srcRect, dstRect, mode, maskRgn); RGBForeColor(&saveFG); // restore the foreground color RGBBackColor(&saveBG); // restore the background color } // DrawColorizedPicture works just like DrawPicture, except it colorizes the // the pixelmap portions of the picture according to the global variables // gFGColor and gBGColor. It assumes the target port is a color port pascal void DrawColorizedPicture(PicHandle ph, Rect *targetBounds, RGBColor *fg, RGBColor *bg) { CQDProcs myProcs; // new bottlenecks CQDProcs *oldProcs; // saved bottlenecks GrafPtr curPort; // the active GrafPort static QDBitsUPP theUPP = NULL; // the UPP for our StdBits replacement if (theUPP == NULL) { // allocate the UPP if it does not exist theUPP = NewQDBitsProc(myQDBitsProcPtr); } gFGColor = *fg; // communicate colorization to the bottleneck gBGColor = *bg; GetPort(&curPort); // find the current port SetStdCProcs(&myProcs); // initialize the bottleneck record myProcs.bitsProc = theUPP; // insert our StdBits Bottleneck // save the previous Bottleneck record oldProcs = ((CGrafPort*)curPort)->grafProcs; // attach our bottleneck record ((CGrafPort*)curPort)->grafProcs = &myProcs; DrawPicture(ph, targetBounds); // draw the picture // restore the bottlneck record ((CGrafPort*)curPort)->grafProcs = oldProcs; }
B.J. Buchalter
bj@metric-halo.com
- SPREAD THE WORD:
- Slashdot
- Digg
- Del.icio.us
- Newsvine