开发者

Multiplying RGBA with two CGImageRefs

I'd like to multiply r, g, b and a values of two CGImages, to use a single image as both a mask (in its alpha channel) and tint (in the rgb channels). I first tried simply:

CGContextDrawImage(context, CGRectMake(0, 0, _w, _h), handle());
CGContextSetBlendMode(context, kCGBlendModeMultiply);
CGContextDrawImage(context, CGRectMake(0, 0, other->width(), other->height()开发者_开发百科), over);

However, this only tints, and does not mask. Thus, I extracted the alpha from the masking image into a CGImage mask grayscale image (using a CGDataProvider) and used that as a mask on the context:

// "mask" is "other"'s alpha channel as an inverted grayscale image
CGContextSaveGState(context);
CGContextClipToMask(context, CGRectMake(0, 0, other->width(), other->height()), mask);
CGImageRelease(mask);
CGContextDrawImage(context, CGRectMake(0, 0, _w, _h), handle());
CGContextRestoreGState(context); // Don't apply the clip mask to 'other', since it already has it
CGContextSetBlendMode(context, kCGBlendModeMultiply);
CGContextDrawImage(context, CGRectMake(0, 0, other->width(), other->height()), other->handle());

It still won't look right, though. The image gets lighter; should a multiplied image be always at least darker? Previews of images at:

http://dl.dropbox.com/u/6775/multiply/index.html

Thanks in advance for enlightenment :)


The first thing is that you don't need to extract the alpha channel to a separate channel to do masking. You can just draw it with kCGBlendModeDestinationIn. For an inverted mask, same thing, but with kCGBlendModeDestinationOut.

So, the solution is to draw the second image with Multiply, then draw it again with Destination In or Out.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜