Iphone 更改图像颜色
我正在尝试更改图像的颜色。我的代码:Iphone 更改图像颜色,iphone,objective-c,ios,uiimage,cgcontext,Iphone,Objective C,Ios,Uiimage,Cgcontext,我正在尝试更改图像的颜色。我的代码: -(UIImage *)coloredImage:(UIImage *)firstImage withColor:(UIColor *)color { UIGraphicsBeginImageContext(firstImage.size); CGContextRef context = UIGraphicsGetCurrentContext(); [color setFill]; CGContextTranslateCT
-(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;
}
这段代码可以工作,但获得的图像并不像应该的那个样好:返回图像的边界像素是间歇性的,不像我的第一幅图像那个样平滑。如何解决此问题?另一种给图像着色的方法是简单地将其乘以恒定的颜色。有时,这是更好的,因为它不会“提升”黑色区域中的颜色值;它使图像中的相对强度保持不变。使用覆盖层作为色调往往会使对比度变平 这是我使用的代码:
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
}
}
这与上面的答案基本相同,但略为缩短。这仅将图像作为遮罩,实际上不会“倍增”或对图像着色 目标C:
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));
UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIColor*color=;
UIImage*图像=;//要遮罩的图像
UIGraphicsBeginImageContextWithOptions(image.size、NO、image.scale);
CGContextRef context=UIGraphicsGetCurrentContext();
[颜色设置填充];
CGContextTranslateCm(上下文,0,image.size.height);
CGContextScaleCTM(上下文,1.0,-1.0);
CGContextClipToMask(上下文,CGRectMake(0,0,image.size.width,image.size.height),[image-CGImage]);
CGContextFillRect(上下文,CGRectMake(0,0,image.size.width,image.size.height));
UIImage*coloredImg=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsSendImageContext();
斯威夫特:
let color: UIColor = <# UIColor #>
let image: UIImage = <# UIImage #> // Image to mask with
UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
let context = UIGraphicsGetCurrentContext()
color.setFill()
context?.translateBy(x: 0, y: image.size.height)
context?.scaleBy(x: 1.0, y: -1.0)
context?.clip(to: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height), mask: image.cgImage!)
context?.fill(CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
let coloredImg = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let color:UIColor=
let image:UIImage=//要使用其进行遮罩的图像
UIGraphicsBeginImageContextWithOptions(image.size、false、image.scale)
let context=UIGraphicsGetCurrentContext()
color.setFill()
上下文?.translateBy(x:0,y:image.size.height)
上下文?.scaleBy(x:1.0,y:-1.0)
context?.clip(到:CGRect(x:0,y:0,宽度:image.size.width,高度:image.size.height),掩码:image.cgImage!)
上下文?.fill(CGRect(x:0,y:0,宽度:image.size.width,高度:image.size.height))
让coloredImg=UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsSendImageContext()
自从iOS 7以来,这是最简单的方法
目标-C:
theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];
theImageView.image = theImageView.image?.imageWithRenderingMode(.AlwaysTemplate)
theImageView.tintColor = UIColor.magentaColor()
theImageView.image = theImageView.image?.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = .magenta
Swift 2.0:
theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];
theImageView.image = theImageView.image?.imageWithRenderingMode(.AlwaysTemplate)
theImageView.tintColor = UIColor.magentaColor()
theImageView.image = theImageView.image?.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = .magenta
Swift 4.0:
theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];
theImageView.image = theImageView.image?.imageWithRenderingMode(.AlwaysTemplate)
theImageView.tintColor = UIColor.magentaColor()
theImageView.image = theImageView.image?.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = .magenta
情节提要:
theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];
theImageView.image = theImageView.image?.imageWithRenderingMode(.AlwaysTemplate)
theImageView.tintColor = UIColor.magentaColor()
theImageView.image = theImageView.image?.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = .magenta
首先在资源中将图像配置为模板(在右侧栏上-渲染为)。然后图像的颜色将是应用的着色颜色。
在Swift 3.0中
imageView.image? = (imageView.image?.withRenderingMode(.alwaysTemplate))!
imageView.tintColor = UIColor.magenta
yourImage.image? = (yourImage.image?.imageWithRenderingMode(.AlwaysTemplate))!
yourImage.tintColor = UIColor.magentaColor()
在Swift 2.0中
imageView.image? = (imageView.image?.withRenderingMode(.alwaysTemplate))!
imageView.tintColor = UIColor.magenta
yourImage.image? = (yourImage.image?.imageWithRenderingMode(.AlwaysTemplate))!
yourImage.tintColor = UIColor.magentaColor()
祝你们Swift先锋们玩得愉快基于@Anna的回答,我为Swift 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
}
Anna的代码可以通过使用kCGBlendModeNormal而不是kCGBlendModeMultiply在彩色.image背景上复制UIImage.image。例如,
self.main image.image=[self-NormalImageByConstantColor:self.main image.image withColor:yourColor]
将mainImage.image的内容放置在着色yourColor上,同时保留yourColor的不透明度。这解决了我在图像后面放置不透明度背景色的问题,该图像将保存到相机卷中。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!
}
}
如果您不必以编程方式进行,那么可以使用Xcode UI进行 如果转到“图像资源”文件夹中的图像,请打开右侧的检查器,此时会出现“渲染为”下拉列表,其中包含以下选项:
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!
}
}
以下是我对@Anna答案的改编。这里有两个关键点:
- 在混合模式下使用
destinationIn
- 调用
以获得平滑图像UIGraphicsBeginImageContextWithOptions(backgroundSize,false,UIScreen.main.scale)
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!
}
}
Swift 4.2解决方案
extension UIImage {
func withColor(_ color: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
guard let ctx = UIGraphicsGetCurrentContext(), let cgImage = cgImage else { return self }
color.setFill()
ctx.translateBy(x: 0, y: size.height)
ctx.scaleBy(x: 1.0, y: -1.0)
ctx.clip(to: CGRect(x: 0, y: 0, width: size.width, height: size.height), mask: cgImage)
ctx.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
guard let colored = UIGraphicsGetImageFromCurrentImageContext() else { return self }
UIGraphicsEndImageContext()
return colored
}
}
// Usage:
// let redImage = UIImage().withColor(.red)
从iOS 10开始,您可以使用UIGraphicsSimageRenderer:
extension UIImage {
func colored(_ color: UIColor) -> UIImage {
let renderer = UIGraphicsImageRenderer(size: size)
return renderer.image { context in
color.setFill()
self.draw(at: .zero)
context.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height), blendMode: .sourceAtop)
}
}
}
对于iOS 13及更新版本:
让redImage=image.withTintColor(.red,renderingMode:.alwaysTemplate)
您应该使用UIGraphicsBeginImageContextWithOptions(image.size,NO,image.scale)代码>因为您的版本只会创建非视网膜图形。根据我的经验,user1270061就是这样做的。“燃烧”的另一个答案显然需要特定颜色的源图像。这一个只使用源像素中的alpha值,并将其与所需的颜色相结合-完美。完美-唯一的答案对我来说很好。(5月16日)这正是我想要的解决方案!谢谢如果我想制作一个虚拟的壁画应用程序呢?这是可行的,如果你只想给图像中的墙壁上色怎么办。请查看此链接:-这比其他一些解决方案效果好得多。这对我来说只着色了对象背景,而不是对象本身。可能重复“UIImageRenderingModeAlwaysTemplate:始终将图像绘制为模板图像,忽略其颜色信息。”很好!在Swift 2.0+theImageView.image?=(图像视图.image?.imageWithRenderingMode(.AlwaysTemplate))!theImageView.tintColor=UIColor.PigentaColor()
@AnkishJain此方法是否存在任何性能问题?这不会更改图像的颜色,而是指示视图以不同的色调(颜色)渲染图像。@Womble不太可能。您可以将其用于任何UIImage<代码>img=[img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];[按钮setTintColor:[UIColor REDCLOR]];[按钮设置图像:img for状态:uicontrol状态正常]代码>@Ankish谢谢!您正在使用XCODE 8吗?为什么在扩展UIImage时要传递映像?您应该删除方法的static关键字,只需在内部使用self