如何在iPhone上以编程方式着色图像?
我想用一个颜色参考色调图像。 结果应该看起来像Photoshop中的Multiply混合模式,其中白色将被replace为tint :
我会不断地改变颜色值。
跟进:我会把代码在我的ImageView的drawRect:方法,这是什么?
与往常一样, 代码片段将大大有助于我的理解,而不是链接。
更新:使用代码Raminbuild议UIImageView的子类。
我把这个viewDidLoad:我的视图控制器:
[self.lena setImage:[UIImage imageNamed:kImageName]]; [self.lena setOverlayColor:[UIColor blueColor]]; [super viewDidLoad];
我看到图像,但没有被着色。 我也尝试加载其他图像,在IB中设置图像,并调用setNeedsDisplay:在我的视图控制器。
更新 :drawRect:没有被调用。
最后更新:我发现一个老的项目,有一个imageView设置正确,所以我可以testingRamin的代码,它的作品就像一个魅力!
最后,最后更新:
对于那些刚学习Core Graphics的人来说,这是最简单的方法。
在你的子类UIView中:
- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColor(context, CGColorGetComponents([UIColor colorWithRed:0.5 green:0.5 blue:0 alpha:1].CGColor)); // don't make color too saturated CGContextFillRect(context, rect); // draw base [[UIImage imageNamed:@"someImage.png"] drawInRect: rect blendMode:kCGBlendModeOverlay alpha:1.0]; // draw image }
首先,您需要inheritanceUIImageView并覆盖drawRect方法。 你的类需要一个UIColor属性(我们称之为overlayColor)来保存混合颜色和一个自定义设置器,当颜色改变时强制重绘。 像这样的东西:
- (void) setOverlayColor:(UIColor *)newColor { if (overlayColor) [overlayColor release]; overlayColor = [newColor retain]; [self setNeedsDisplay]; // fires off drawRect each time color changes }
在drawRect方法中,您需要先绘制图像,然后用填充了所需颜色的矩形和适当的混合模式叠加,如下所示:
- (void) drawRect:(CGRect)area { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); // Draw picture first // CGContextDrawImage(context, self.frame, self.image.CGImage); // Blend mode could be any of CGBlendMode values. Now draw filled rectangle // over top of image. // CGContextSetBlendMode (context, kCGBlendModeMultiply); CGContextSetFillColor(context, CGColorGetComponents(self.overlayColor.CGColor)); CGContextFillRect (context, self.bounds); CGContextRestoreGState(context); }
通常为了优化绘图,将实际绘图限制为仅传递给drawRect的区域,但是由于每次颜色改变时必须重绘背景图像,因此整个事物将需要刷新。
要使用它创build对象的一个实例,然后将image
属性(从UIImageViewinheritance)设置为图片和overlayColor
到UIColor值(混合级别可以通过更改您传递的颜色的Alpha值进行调整)。
在iOS7中,他们在UIImageView上引入了tintColor属性,在UIImage上引入了renderingMode。 要在iOS7上着色UIImage,您只需要执行以下操作:
UIImageView* imageView = … UIImage* originalImage = … UIImage* imageForRendering = [originalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; imageView.image = imageForRendering; imageView.tintColor = [UIColor redColor]; // or any color you want to tint it with
只是一个快速的澄清(经过对这个话题的一些研究)。 这里的苹果文件明确指出:
UIImageView
类经过优化将其图像绘制到显示器上。UIImageView
不调用其子类的drawRect:
方法。 如果你的子类需要包含自定义的绘图代码,你应该改为UIView
类的子类。
所以不要浪费任何时间在UIImageView
子类中重写该方法。 而是从UIView
开始。
我想用阿尔法色调图像,我创build了以下类。 如果您发现任何问题,请让我知道。
我已经命名我的类CSTintedImageView
,它从UIView
inheritance,因为UIImageView
不会调用drawRect:
方法,如前面的回复中所述。 我已经设置了一个类似于在UIImageView
类中find的指定的初始化程序。
用法:
CSTintedImageView * imageView = [[CSTintedImageView alloc] initWithImage:[UIImage imageNamed:@"image"]]; imageView.tintColor = [UIColor redColor];
CSTintedImageView.h
@interface CSTintedImageView : UIView @property (strong, nonatomic) UIImage * image; @property (strong, nonatomic) UIColor * tintColor; - (id)initWithImage:(UIImage *)image; @end
CSTintedImageView.m
#import "CSTintedImageView.h" @implementation CSTintedImageView @synthesize image=_image; @synthesize tintColor=_tintColor; - (id)initWithImage:(UIImage *)image { self = [super initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)]; if(self) { self.image = image; //set the view to opaque self.opaque = NO; } return self; } - (void)setTintColor:(UIColor *)color { _tintColor = color; //update every time the tint color is set [self setNeedsDisplay]; } - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); //resolve CG/iOS coordinate mismatch CGContextScaleCTM(context, 1, -1); CGContextTranslateCTM(context, 0, -rect.size.height); //set the clipping area to the image CGContextClipToMask(context, rect, _image.CGImage); //set the fill color CGContextSetFillColor(context, CGColorGetComponents(_tintColor.CGColor)); CGContextFillRect(context, rect); //blend mode overlay CGContextSetBlendMode(context, kCGBlendModeOverlay); //draw the image CGContextDrawImage(context, rect, _image.CGImage); } @end
这可能是非常有用的:PhotoshopFramework是一个强大的库来操纵Objective-C上的图像。 这是为了使Adobe Photoshop用户熟悉的相同function而开发的。 示例:使用RGB 0-255设置颜色,应用混合文件,转换…
是开源的,这里是项目链接: https : //sourceforge.net/projects/photoshopframew/
UIImage * image = mySourceImage; UIColor * color = [UIColor yellowColor]; UIGraphicsBeginImageContext(image.size); [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height) blendMode:kCGBlendModeNormal alpha:1]; UIBezierPath * path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, image.size.width, image.size.height)]; [color setFill]; [path fillWithBlendMode:kCGBlendModeMultiply alpha:1]; //look up blending modes for your needs UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); //use newImage for something
这是实现图像着色的另一种方式,特别是如果您已经在使用QuartzCore来做其他事情了。 这是我对类似问题的回答 。
导入QuartzCore:
#import <QuartzCore/QuartzCore.h>
创build透明的CALayer,并将其添加为您想要着色的图像的子图层:
CALayer *sublayer = [CALayer layer]; [sublayer setBackgroundColor:[UIColor whiteColor].CGColor]; [sublayer setOpacity:0.3]; [sublayer setFrame:toBeTintedImage.frame]; [toBeTintedImage.layer addSublayer:sublayer];
添加QuartzCore到你的项目框架列表(如果它不在那里),否则你会得到像这样的编译器错误:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_CALayer"
对于那些尝试inheritance一个UIImageView类并被卡住“drawRect:is not being called”的人,请注意,您应该inheritance一个UIView类,因为对于UIImageView类,不调用“drawRect:”方法。 阅读更多在这里: drawRect不被称为我的UIImageView的子类
对于Swift 2.0,
let image: UIImage! = UIGraphicsGetImageFromCurrentImageContext() imgView.image = imgView.image!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) imgView.tintColor = UIColor(red: 51/255.0, green: 51/255.0, blue: 51/255.0, alpha: 1.0)
我能想到的唯一的事情就是创build一个具有所需颜色的矩形大部分透明视图,并将它作为子视图添加到图像视图中。 我不确定这是否能够以你想象的方式真实地呈现图像,但我不确定你将如何破解图像,并select性地replace某些颜色……对我而言,这听起来相当雄心勃勃。
例如:
UIImageView *yourPicture = (however you grab the image); UIView *colorBlock = [[UIView alloc] initWithFrame:yourPicture.frame]; //Replace RGB and A with values from 0 - 1 based on your color and transparency colorBlock.backgroundColor = [UIColor colorWithRed:R green:G blue:B alpha:A]; [yourPicture addSubView:colorBlock];
UIColor的文档:
colorWithRed:green:blue:alpha: Creates and returns a color object using the specified opacity and RGB component values. + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha Parameters red - The red component of the color object, specified as a value from 0.0 to 1.0. green - The green component of the color object, specified as a value from 0.0 to 1.0. blue - The blue component of the color object, specified as a value from 0.0 to 1.0. alpha - The opacity value of the color object, specified as a value from 0.0 to 1.0. Return Value The color object. The color information represented by this object is in the device RGB colorspace.
另外,您可能需要考虑caching合成图像的性能,并将其渲染到drawRect :,然后更新它,如果脏标志确实很脏。 虽然你可能会经常改变它,但有些情况下可能会有画图,而且你并不脏,所以你可以简单地从caching中刷新。 如果内存比性能更重要的话,你可以忽略这个:)
我有一个库,我为此开放源代码: ios图像filter