【问题标题】:iOS: Applying a RGB filter to a greyscale PNGiOS:将 RGB 滤镜应用于灰度 PNG
【发布时间】:2011-07-13 18:35:02
【问题描述】:

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

(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();
    }

【问题讨论】:

  • 我很好奇您的代码示例中看似多余的 {} - 这些是做什么的
  • 它们使代码更清晰/封装变量
  • 如果您想支持视网膜图像,请确保使用UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0); 而不是UIGraphicsBeginImageContext( targetSize );。参数NO0.0 分别表示使用不透明上下文(YES 或 NO 值)和比例因子(设备比例因子为 0.0,显式比例因子为任何其他值)。

标签: ios image-processing filter core-graphics


【解决方案1】:

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

【讨论】:

  • 我认为这只会给出这里提到的问题:forums.macrumors.com/showthread.php?t=547339
  • 如果 CGContextFillRect 消除了 alpha 通道,请尝试使用 kCGBlendModeDestinationIn 在顶部绘制原始图像以重新应用它。
  • 我刚试过(我已经修改了我的问题)......我仍然无法摆脱它们的红色背景。有什么想法吗?
  • @Pi: drawInRect: 不尊重您在基础上下文中设置的混合模式。请改用drawInRect:blendMode:alpha:
  • 太棒了!谢谢——我永远也想不通!
【解决方案2】:

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

【讨论】:

【解决方案3】:

这是对问题答案的改进和@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]];

【讨论】:

    猜你喜欢
    • 2018-01-19
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    • 1970-01-01
    • 2014-02-11
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多