UIImageView将图像过滤成纯色

时间:2013-08-19 21:39:44

标签: iphone ios core-graphics core-image

我有一些带有透明背景的彩色图标。我想根据程序的状态自动显示那些(纯色灰色)的平面版本。

我可以使用Core Image过滤器吗?还有另一种方式吗?

3 个答案:

答案 0 :(得分:2)

子类并创建自己的UIImageView(或具有UIImageView属性的UIView)并覆盖drawRect,您将希望将上下文剪切为图像蒙版,然后填充纯色:

- (void)drawRect:(CGRect)rect;
{
  CGRect bounds = [self bounds];
  [[UIColor grayColor] setFill];
  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextClipToMask(context, bounds, [image CGImage]);
  CGContextFillRect(context, bounds);
}

答案 1 :(得分:1)

我想我以前做过同样的事情,我有一些彩色图标,但我需要保持形状并将颜色改为单色。所以我写了一个UIImage的扩展。

这是代码,希望这对你有帮助。

的UIImage + MonoImage.h

//
//  UIImage+MonoImage.h
//  ShiftScheduler
//
//  Created by Zhang Jiejing on 12-2-11.
//  Copyright (c) 2012. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface UIImage (MonoImage)

// This function create a Image Context and draw the image with mask
// then clip the context to mask
// then fill the color user choosed.
// that can create a image shape with specify color icon.
+ (UIImage *) generateMonoImage: (UIImage *)icon withColor:(UIColor *)color;
@end

的UIImage + MonoImage.m

//
//  UIImage+MonoImage.m
//  ShiftScheduler
//
//  Created by Jiejing Zhang on 12-2-11.
//  Copyright (c) 2012. All rights reserved.
//

#import "UIImage+MonoImage.h"

@implementation UIImage (MonoImage)

+ (UIImage *) generateMonoImage: (UIImage *)icon withColor:(UIColor *)color
{
    UIImage *finishImage;
    CGImageRef alphaImage = CGImageRetain(icon.CGImage);
    CGColorRef colorref = CGColorRetain(color.CGColor);

    UIGraphicsBeginImageContext(icon.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGRect imageArea = CGRectMake (0, 0,
                                   icon.size.width, icon.size.height);

    // Don't know why if I don't translate the CTM, the image will be a *bottom* up
    // aka, head on bottom shape, so I need use TranlateCTM and ScaleCTM to let
    // all y-axis to be rotated.
    CGFloat height = icon.size.height;
    CGContextTranslateCTM(ctx, 0.0, height);
    CGContextScaleCTM(ctx, 1.0, -1.0);

    CGContextClipToMask(ctx, imageArea , alphaImage);

    CGContextSetFillColorWithColor(ctx, colorref);
    CGContextFillRect(ctx, imageArea);
    CGImageRelease(alphaImage);
    CGColorRelease(colorref);

    finishImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return finishImage;
}


@end

答案 2 :(得分:0)

这是我创建的UIView子类。非常感谢Oliver指出这一点。我以为你当时不能继承UIImageView。

@interface SolidColorImageView : UIView
@property (nonatomic, strong) UIImage * image;
@property (nonatomic) BOOL enabled;
@end






@implementation SolidColorImageView

- (void)setImage:(UIImage *)image {
    _image = image;
    [self setNeedsDisplay];
}

- (void)setEnabled:(BOOL)enabled {
    _enabled = enabled;
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect;
{
    CGRect bounds = [self bounds];
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, bounds);

    [[UIColor whiteColor] setFill];
    CGContextFillRect(context, bounds);

    CGRect aspectFitRect = [self aspectFit:self.image inFrame:bounds];

    if (self.image && self.enabled == NO) {
        [[UIColor grayColor] setFill];
        CGContextTranslateCTM(context, 0, bounds.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);

        CGContextClipToMask(context, aspectFitRect, [self.image CGImage]);
        CGContextFillRect(context, bounds);        
    } else if (self.image) {
        [self.image drawInRect:aspectFitRect];
    }
}


-(CGRect)aspectFit:(UIImage*)image inFrame:(CGRect)outerFrame {

    CGSize imageSize = image.size;
    CGSize viewSize = outerFrame.size;

    float hfactor = imageSize.width / viewSize.width;
    float vfactor = imageSize.height / viewSize.height;

    float factor = fmax(hfactor, vfactor);

    // Divide the size by the greater of the vertical or horizontal shrinkage factor
    float newWidth = imageSize.width / factor;
    float newHeight = imageSize.height / factor;
    float newX = outerFrame.origin.x + (outerFrame.size.width - newWidth)/2;
    float newY = outerFrame.origin.y + (outerFrame.size.height - newHeight)/2;

    CGRect newRect = CGRectMake(newX, newY, newWidth, newHeight);
    return newRect;
}

@end