iOS:将RGB滤镜应用于灰度PNG

时间:2011-07-13 18:35:02

标签: ios image-processing filter core-graphics

我有一个灰度宝石顶视图。

(PNG格式,因此有alpha分量)

我想从这张图片中创建12个小尺寸按钮,每个按钮的颜色不同。

为了整洁,我想在代码中执行此操作,而不是在某些艺术包中进行外部操作。

任何人都可以提供一种方法(甚至是一些代码)吗?

PS我知道如何使用大量的代码在GL中完成它,我希望有一种更简单的方式使用核心图形/核心动画

编辑:工作解决方案,感谢以下答案的精彩

    CGSize targetSize = (CGSize){100,100};
    UIImage* image;
    {
        CGRect rect = (CGRect){ .size = targetSize };

        UIGraphicsBeginImageContext( targetSize );
        {
            CGContextRef X = UIGraphicsGetCurrentContext();

            UIImage* uiGem = [UIImage imageNamed: @"GemTop_Dull.png"];

            // draw gem
            [uiGem drawInRect: rect];

            // overlay a red rectangle
            CGContextSetBlendMode( X, kCGBlendModeColor ) ;
            CGContextSetRGBFillColor ( X,  0.9, 0, 0,  1 );
            CGContextFillRect ( X, rect );

            // redraw gem 
            [uiGem drawInRect: rect
                    blendMode: kCGBlendModeDestinationIn
                        alpha: 1. ];

            image = UIGraphicsGetImageFromCurrentImageContext();
        }
        UIGraphicsEndImageContext();
    }

3 个答案:

答案 0 :(得分:4)

最简单的方法是将图像绘制为RGB颜色空间CGBitmapContext,使用CGContextSetBlendMode设置kCGBlendModeColor,然后使用纯色绘制(例如与CGContextFillRect)。

答案 1 :(得分:1)

最好看的结果将来自使用灰度值来索引到从所需结果的最暗到最亮颜色的渐变。不幸的是,我不知道核心图形的具体细节。

答案 2 :(得分:0)

这是对问题答案和@Anomie

实施的改进

首先,将它放在UIButton类或视图控制器的开头。它会从UIColor转换为RGBA值,稍后您将需要它。

typedef enum { R, G, B, A } UIColorComponentIndices;


@implementation UIColor (EPPZKit)

- (CGFloat)redRGBAValue {
    return CGColorGetComponents(self.CGColor)[R];
}

- (CGFloat)greenRGBAValue  {
    return CGColorGetComponents(self.CGColor)[G];
}

- (CGFloat)blueRGBAValue  {
    return CGColorGetComponents(self.CGColor)[B];
}

- (CGFloat)alphaRGBAValue  {
    return CGColorGetComponents(self.CGColor)[A];
}

@end

现在,确保在IB中有自定义图像按钮,带有灰度图像和右边框。这比以编程方式创建自定义图像按钮要好得多,因为:

  • 您可以让IB加载图片,而不必手动加载
  • 您可以调整按钮并在IB中直观地看到它
  • 您的IB在运行时看起来更像您的应用
  • 您不必手动设置框架

假设您有按钮在IB中(靠近底部将支持以编程方式创建它),请将此方法添加到视图控制器或按钮Cub类:

- (UIImage*)customImageColoringFromButton:(UIButton*)customImageButton fromColor:(UIColor*)color {
    UIImage *customImage = [customImageButton.imageView.image copy];

    UIGraphicsBeginImageContext(customImageButton.imageView.frame.size); {
        CGContextRef X = UIGraphicsGetCurrentContext();

        [customImage drawInRect: customImageButton.imageView.frame];

        // Overlay a colored rectangle
        CGContextSetBlendMode( X, kCGBlendModeColor) ;
        CGContextSetRGBFillColor ( X, color.redRGBAValue, color.greenRGBAValue, color.blueRGBAValue, color.alphaRGBAValue);
        CGContextFillRect ( X, customImageButton.imageView.frame);

        // Redraw
        [customImage drawInRect:customImageButton.imageView.frame blendMode: kCGBlendModeDestinationIn alpha: 1.0];

        customImage = UIGraphicsGetImageFromCurrentImageContext();
    }
    UIGraphicsEndImageContext();

    return customImage;
}

然后,您需要在视图控制器或按钮子类中的设置方法中调用它,并将按钮的imageView设置为:

[myButton.imageView setImage:[self customImageColoringFromButton:myButton fromColor:desiredColor]];

如果您使用IB创建按钮,请使用此方法:

- (UIImage*)customImageColoringFromImage:(UIImage*)image fromColor:(UIColor*)color fromFrame:(CGRect)frame {
    UIImage *customImage = [image copy];

    UIGraphicsBeginImageContext(frame.size); {
        CGContextRef X = UIGraphicsGetCurrentContext();

        [customImage drawInRect: frame];

        // Overlay a colored rectangle
        CGContextSetBlendMode( X, kCGBlendModeColor) ;
        CGContextSetRGBFillColor ( X, color.redRGBAValue, color.greenRGBAValue, color.blueRGBAValue, color.alphaRGBAValue);
        CGContextFillRect ( X, frame);

        // Redraw
        [customImage drawInRect:frame blendMode: kCGBlendModeDestinationIn alpha: 1.0];

        customImage = UIGraphicsGetImageFromCurrentImageContext();
    }
    UIGraphicsEndImageContext();

    return customImage;
}

并将其命名为:

[self.disclosureButton.imageView setImage:[self customImageColoringFromImage:[UIImage imageNamed:@"GemTop_Dull.png"] fromColor:desiredColor fromFrame:desiredFrame]];