更改UIImage颜色

我正在尝试改变UIImage的颜色。 我的代码:

-(UIImage *)coloredImage:(UIImage *)firstImage withColor:(UIColor *)color { UIGraphicsBeginImageContext(firstImage.size); CGContextRef context = UIGraphicsGetCurrentContext(); [color setFill]; CGContextTranslateCTM(context, 0, firstImage.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextSetBlendMode(context, kCGBlendModeCopy); CGRect rect = CGRectMake(0, 0, firstImage.size.width, firstImage.size.height); CGContextDrawImage(context, rect, firstImage.CGImage); CGContextClipToMask(context, rect, firstImage.CGImage); CGContextAddRect(context, rect); CGContextDrawPath(context,kCGPathElementMoveToPoint); UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return coloredImg; } 

此代码工作,但获得的图像是不是应该如此:返回的图像的边界像素是间歇性的,不像我的第一个图像那么光滑。 我该如何解决这个问题?

从iOS 7开始,这是最简单的方法。

 theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [theImageView setTintColor:[UIColor redColor]]; 

在Swift 2.0+中

 theImageView.image? = (theImageView.image?.imageWithRenderingMode(.AlwaysTemplate))! theImageView.tintColor = UIColor.magentaColor() 

通过故事板

首先将图像configuration为模板(在右栏 – 渲染为)您的资产。 然后,图像的颜色将是应用的色调颜色。 在这里输入图像说明

这几乎是上面的答案,但略有缩短。 这只将图像作为蒙版,并不实际“乘”或彩色图像。

  UIColor *color = <# UIColor #>; UIImage *image = <# UIImage #>;// Image to mask with UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale); CGContextRef context = UIGraphicsGetCurrentContext(); [color setFill]; CGContextTranslateCTM(context, 0, image.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextClipToMask(context, CGRectMake(0, 0, image.size.width, image.size.height), [image CGImage]); CGContextFillRect(context, CGRectMake(0, 0, image.size.width, image.size.height)); coloredImg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

在Swift 3.0中

 imageView.image? = (imageView.image?.withRenderingMode(.alwaysTemplate))! imageView.tintColor = UIColor.magenta 

在Swift 2.0中

 yourImage.image? = (yourImage.image?.imageWithRenderingMode(.AlwaysTemplate))! yourImage.tintColor = UIColor.magentaColor() 

享受你斯威夫特的先驱

另一种对图像进行着色的方法是简单地将其乘以一个常量的颜色。 有时候,这是可取的,因为它不会“提升”黑色区域的颜色值; 它保持图像中的相对强度相同。 使用覆盖作为色调倾向于使对比度变平。

这是我使用的代码:

 UIImage *MultiplyImageByConstantColor( UIImage *image, UIColor *color ) { CGSize backgroundSize = image.size; UIGraphicsBeginImageContext(backgroundSize); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGRect backgroundRect; backgroundRect.size = backgroundSize; backgroundRect.origin.x = 0; backgroundRect.origin.y = 0; CGFloat r,g,b,a; [color getRed:&r green:&g blue:&b alpha:&a]; CGContextSetRGBFillColor(ctx, r, g, b, a); CGContextFillRect(ctx, backgroundRect); CGRect imageRect; imageRect.size = image.size; imageRect.origin.x = (backgroundSize.width - image.size.width)/2; imageRect.origin.y = (backgroundSize.height - image.size.height)/2; // Unflip the image CGContextTranslateCTM(ctx, 0, backgroundSize.height); CGContextScaleCTM(ctx, 1.0, -1.0); CGContextSetBlendMode(ctx, kCGBlendModeMultiply); CGContextDrawImage(ctx, imageRect, image.CGImage); UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

Swift版本

 extension UIImage{ static func multiplyImageByConstantColor(image:UIImage,color:UIColor)->UIImage{ let backgroundSize = image.size UIGraphicsBeginImageContext(backgroundSize) let ctx = UIGraphicsGetCurrentContext() var backgroundRect=CGRect() backgroundRect.size = backgroundSize backgroundRect.origin.x = 0 backgroundRect.origin.y = 0 var r:CGFloat var g:CGFloat var b:CGFloat var a:CGFloat color.getRed(&r, green: &g, blue: &b, alpha: &a) CGContextSetRGBFillColor(ctx, r, g, b, a) CGContextFillRect(ctx, backgroundRect) var imageRect=CGRect() imageRect.size = image.size imageRect.origin.x = (backgroundSize.width - image.size.width)/2 imageRect.origin.y = (backgroundSize.height - image.size.height)/2 // Unflip the image CGContextTranslateCTM(ctx, 0, backgroundSize.height) CGContextScaleCTM(ctx, 1.0, -1.0) CGContextSetBlendMode(ctx, .Multiply) CGContextDrawImage(ctx, imageRect, image.CGImage) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } } 

基于@安娜的答案,我重写为迅速2.2和处理图像与alpha通道:

 static func multiplyImageByConstantColor(image:UIImage,color:UIColor)->UIImage{ let backgroundSize = image.size UIGraphicsBeginImageContext(backgroundSize) let ctx = UIGraphicsGetCurrentContext() var backgroundRect=CGRect() backgroundRect.size = backgroundSize backgroundRect.origin.x = 0 backgroundRect.origin.y = 0 var r:CGFloat = 0 var g:CGFloat = 0 var b:CGFloat = 0 var a:CGFloat = 0 color.getRed(&r, green: &g, blue: &b, alpha: &a) CGContextSetRGBFillColor(ctx, r, g, b, a) // Unflip the image CGContextTranslateCTM(ctx, 0, backgroundSize.height) CGContextScaleCTM(ctx, 1.0, -1.0) CGContextClipToMask(ctx, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage); CGContextFillRect(ctx, backgroundRect) var imageRect=CGRect() imageRect.size = image.size imageRect.origin.x = (backgroundSize.width - image.size.width)/2 imageRect.origin.y = (backgroundSize.height - image.size.height)/2 CGContextSetBlendMode(ctx, .Multiply) CGContextDrawImage(ctx, imageRect, image.CGImage) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } 

如果你不需要编程,你可以使用Xcode UI来完成。

如果您转到图片资源文件夹中的图片,请打开右侧的检查器,然后出现“渲染为”下拉列表,其中包含以下选项:

  1. 默认
  2. 原版的
  3. 模板

一旦你做了模板select,你可以改变图像的tintColor,不pipe你使用的是Xcode storyboard UI还是编程方式。

在这里输入图像说明

看到这个图像:

在这里输入图像说明

这是我对@安娜的回答的改编。 这里有两个关键点:

  • 使用destinationIn混合模式
  • 调用UIGraphicsBeginImageContextWithOptions(backgroundSize, false, UIScreen.main.scale)来获得平滑的图像

Swift 3中的代码:

 extension UIImage { static func coloredImage(image: UIImage?, color: UIColor) -> UIImage? { guard let image = image else { return nil } let backgroundSize = image.size UIGraphicsBeginImageContextWithOptions(backgroundSize, false, UIScreen.main.scale) let ctx = UIGraphicsGetCurrentContext()! var backgroundRect=CGRect() backgroundRect.size = backgroundSize backgroundRect.origin.x = 0 backgroundRect.origin.y = 0 var r:CGFloat = 0 var g:CGFloat = 0 var b:CGFloat = 0 var a:CGFloat = 0 color.getRed(&r, green: &g, blue: &b, alpha: &a) ctx.setFillColor(red: r, green: g, blue: b, alpha: a) ctx.fill(backgroundRect) var imageRect = CGRect() imageRect.size = image.size imageRect.origin.x = (backgroundSize.width - image.size.width) / 2 imageRect.origin.y = (backgroundSize.height - image.size.height) / 2 // Unflip the image ctx.translateBy(x: 0, y: backgroundSize.height) ctx.scaleBy(x: 1.0, y: -1.0) ctx.setBlendMode(.destinationIn) ctx.draw(image.cgImage!, in: imageRect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } 

}

Anna的代码适用于通过使用kCGBlendModeNormal而不是kCGBlendModeMultiply将UIImage.image复制到彩色的.image背景上。 例如, self.mainImage.image = [self NormalImageByConstantColor: self.mainImage.image withColor: yourColor]; 将mainImage.image的内容放在tint yourColor上,同时保留yourColor的不透明度。 这解决了我的问题,把一个背景颜色不透明的背后保存到相机胶卷的图像。

Swift 3:

 extension UIImage{ static func multiplyImageByConstantColor(image:UIImage,color:UIColor) -> UIImage{ let backgroundSize = image.size UIGraphicsBeginImageContext(backgroundSize) guard let ctx = UIGraphicsGetCurrentContext() else {return image} var backgroundRect=CGRect() backgroundRect.size = backgroundSize backgroundRect.origin.x = 0 backgroundRect.origin.y = 0 var r:CGFloat = 0 var g:CGFloat = 0 var b:CGFloat = 0 var a:CGFloat = 0 color.getRed(&r, green: &g, blue: &b, alpha: &a) ctx.setFillColor(red: r, green: g, blue: b, alpha: a) // Unflip the image ctx.translateBy(x: 0, y: backgroundSize.height) ctx.scaleBy(x: 1.0, y: -1.0) ctx.clip(to: CGRect(0, 0, image.size.width, image.size.height), mask: image.cgImage!) ctx.fill(backgroundRect) var imageRect=CGRect() imageRect.size = image.size imageRect.origin.x = (backgroundSize.width - image.size.width)/2 imageRect.origin.y = (backgroundSize.height - image.size.height)/2 ctx.setBlendMode(.multiply) ctx.draw(image.cgImage!, in: imageRect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } } 

Swift 3.0版本的Anna的奇妙代码:

 extension UIImage{ static func multiplyImageByConstantColor(image:UIImage,color:UIColor)-> UIImage { let backgroundSize = image.size UIGraphicsBeginImageContext(backgroundSize) let ctx = UIGraphicsGetCurrentContext()! var backgroundRect=CGRect() backgroundRect.size = backgroundSize backgroundRect.origin.x = 0 backgroundRect.origin.y = 0 let myFloatForR = 0 var r = CGFloat(myFloatForR) let myFloatForG = 0 var g = CGFloat(myFloatForG) let myFloatForB = 0 var b = CGFloat(myFloatForB) let myFloatForA = 0 var a = CGFloat(myFloatForA) color.getRed(&r, green: &g, blue: &b, alpha: &a) ctx.setFillColor(red: r, green: g, blue: b, alpha: a) ctx.fill(backgroundRect) var imageRect=CGRect() imageRect.size = image.size imageRect.origin.x = (backgroundSize.width - image.size.width)/2 imageRect.origin.y = (backgroundSize.height - image.size.height)/2 // Unflip the image ctx.translateBy(x: 0, y: backgroundSize.height) ctx.scaleBy(x: 1.0, y: -1.0) ctx.setBlendMode(.multiply) ctx.draw(image.cgImage!, in: imageRect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } }