我有一些带有透明背景的彩色图标。我希望能够根据程序的状态自动显示那些(纯灰色)的平面版本。
我可以用 Core Image 过滤器做到这一点吗?还有其他方法吗?
我有一些带有透明背景的彩色图标。我希望能够根据程序的状态自动显示那些(纯灰色)的平面版本。
我可以用 Core Image 过滤器做到这一点吗?还有其他方法吗?
子类化并创建自己的 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);
}
我想我以前做过同样的事情,我有一些彩色图标,但我需要保持形状并将颜色更改为单色。所以我写了一个 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
这是我创建的 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