如何在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 ,它从UIViewinheritance,因为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