1

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

我可以用 Core Image 过滤器做到这一点吗?还有其他方法吗?

4

3 回答 3

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);
}
于 2013-08-19T21:45:10.653 回答
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
于 2013-08-20T03:52:06.373 回答
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
于 2013-08-19T22:18:36.393 回答