9

我需要一个 UIImageView 可以根据标志以彩色或黑白方式绘制自己:

  BOOL isGrey;

我试图通过在石英混合模式设置为颜色的原始图像上绘制一个黑色矩形来做到这一点。这有效,只是它不尊重图像的 alpha 蒙版。

参见插图: 替代文字 http://img214.imageshack.us/img214/1407/converttogreyscaleillo.png

搜索谷歌和 SO,我找到并尝试了几种解决方案,但也没有一个尊重面具。

这是生成上面“我得到的”图像的代码:

 - (void)drawRect:(CGRect)rect {

    if (isGrey) {
        CGContextRef context = UIGraphicsGetCurrentContext();

        // flip orientation
        CGContextTranslateCTM(context, 0, self.bounds.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);

        // draw the image
        CGContextDrawImage(context, self.bounds, self.image.CGImage);

        // set the blend mode and draw rectangle on top of image
        CGContextSetBlendMode(context, kCGBlendModeSaturation);
        CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
        CGContextFillRect(context, rect);       
    } else {
        [self.image drawInRect:rect];
    }
}

是否有一些我忘记设置的 Quartz 绘图模式?我已经查看了 Quartz Programming Guide,但是很难从重叠和超链接的主题中提取您需要的一点信息。

显然,我正在寻找一种适用于任何蒙面形状的图像的通用解决方案,而不仅仅是显示的圆圈。

4

4 回答 4

11

要在尊重图像的 alpha 蒙版的同时绘制形状,只需在绘制之前添加一行:

 CGContextClipToMask(context, self.bounds, image.CGImage);

 // example usage
  - (void)drawRect:(CGRect)rect {

    if (isGrey) {
            CGContextRef context = UIGraphicsGetCurrentContext();

            // flip orientation
            CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
            CGContextScaleCTM(context, 1.0, -1.0);

            // draw the image
            CGContextDrawImage(context, self.bounds, self.image.CGImage);

            // set the blend mode and draw rectangle on top of image
            CGContextSetBlendMode(context, kCGBlendModeColor);
            CGContextClipToMask(context, self.bounds, image.CGImage); // respect alpha mask
            CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
            CGContextFillRect(context, rect);               
    } else {
            [self.image drawInRect:rect];
    }

}

于 2009-09-05T08:52:53.437 回答
1

虽然它不能直接回答你的问题,但是你可以通过使用kCGBlendModeLuminosity混合模式得到你想要的效果:

- (void)drawRect:(CGRect)rect {
    CGSize imageSize = [image size];
    CGContextRef c = UIGraphicsGetCurrentContext();
    if (isGrey)
        CGContextSetBlendMode(c, kCGBlendModeLuminosity);
    CGContextScaleCTM(c, 1.0, -1.0);
    CGContextDrawImage(c, CGRectMake(0.0f, 0.0f, imageSize.width, -imageSize.height), [image CGImage]);
}

此外,传递给的矩形drawRect:是无效区域,而不是整个区域。你应该bounds使用

于 2009-08-28T16:09:56.107 回答
1

我会采取简单的方法,画一个与您拥有的圆形图像大小相同的黑色圆圈。可能不是你要的。

于 2009-08-31T09:38:00.843 回答
0

您可以尝试将遮罩添加到视图的核心动画层。

CALayer *maskLayer = [CALayer layer];
[maskLayer setBounds:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)];

// Center the layer
[maskLayer setPosition:CGPointMake([self view].bounds.size.width/2, 
                          [self view].bounds.size.height/2)];

// Set the cornerRadius to half the width/height to get a circle.
[maskLayer setCornerRadius:50.f];
[maskLayer setMasksToBounds:YES];

// Any solid color will do. Just using black here.
[maskLayer setBackgroundColor:[[UIColor blackColor] CGColor]];

// Set the mask which will only allow that which is in the
// circle show through
[[[self view] layer] setMask:maskLayer];

另一种想法。为什么不能只创建图像的黑白版本并根据您的标志将其换掉?

于 2009-08-28T16:39:14.723 回答