设置模板图像的图像颜色
set image color of a template image
我有这样一张图片:
(呈现为模板图像)
我试过这段代码:
@IBOutlet weak var imgAdd: NSImageView!
imgAdd.layer?.backgroundColor = CGColor.white
当然这只会改变背景颜色。
有没有办法以编程方式更改此图像的颜色?
到目前为止,我已经尝试了下面的代码,但它不起作用。 (图片颜色不变。)
func tintedImage(_ image: NSImage, tint: NSColor) -> NSImage {
guard let tinted = image.copy() as? NSImage else { return image }
tinted.lockFocus()
tint.set()
let imageRect = NSRect(origin: NSZeroPoint, size: image.size)
NSRectFillUsingOperation(imageRect, .sourceAtop)
tinted.unlockFocus()
return tinted
}
imgDok.image = tintedImage(NSImage(named: "myImage")!, tint: NSColor.red)
试试这个有帮助的代码。
Swift 3
let theImageView = UIImageView(image: UIImage(named:"foo")!.withRenderingMode(.alwaysTemplate))
theImageView.tintColor = UIColor.red
在大家的帮助下我找到了解决方案:
(Swift 3)
func tintedImage(_ image: NSImage, tint: NSColor) -> NSImage {
guard let tinted = image.copy() as? NSImage else { return image }
tinted.lockFocus()
tint.set()
let imageRect = NSRect(origin: NSZeroPoint, size: image.size)
NSRectFillUsingOperation(imageRect, .sourceAtop)
tinted.unlockFocus()
return tinted
}
imgDok.image = tintedImage(NSImage(named: "myImage")!, tint: NSColor.red)
重要提示: 在界面生成器中,我必须将图像的 "render as" 设置设置为 "Default".
由于不能使用UIImage函数,可以尝试使用CoreImage(CI)。我不知道是否有更简单的版本,但这个肯定可以!
首先创建 CIImage
let image = CIImage(data: inputImage.tiffRepresentation!)
现在您可以对图像应用各种滤镜和其他东西,这是一个非常强大的工具。
CI 的文档:https://developer.apple.com/documentation/coreimage
这是一个简单的过滤器示例,您基本上是初始化一个过滤器,然后为其设置值,输出并重复。
let yourFilterName = CIFilter(name: "FilterName")
yourFilterName!.setValue(SomeInputImage, forKey: kCIInputImageKey)
yourFilterName!.setValue(10, forKey: kCIInputRadiusKey)
let yourFilterName = yourFilterName!.outputImage
现在您可以将输出转换回 NSImage。
let cgimg = context.createCGImage(yourFilterName!, from: yourFilterName!.extent)
let processedImage = NSImage(cgImage: cgimg!, size: NSSize(width: 0, height: 0))
不得不稍微修改@Ghost108 对 Xcode 9.2 的回答。
NSRectFillUsingOperation(imageRect, .sourceAtop)
至
imageRect.fill(using: .sourceAtop)
谢谢。
Swift 4
Swift 4
的更新答案
请注意,此 NSImage
扩展基于 @Ghost108 和 @Taehyung_Cho 的 答案, 所以更大的功劳归于他们。
extension NSImage {
func tint(color: NSColor) -> NSImage {
let image = self.copy() as! NSImage
image.lockFocus()
color.set()
let imageRect = NSRect(origin: NSZeroPoint, size: image.size)
imageRect.fill(using: .sourceAtop)
image.unlockFocus()
return image
}
}
Swift 4个版本
extension NSImage {
func image(withTintColor tintColor: NSColor) -> NSImage {
guard isTemplate else { return self }
guard let copiedImage = self.copy() as? NSImage else { return self }
copiedImage.lockFocus()
tintColor.set()
let imageBounds = NSMakeRect(0, 0, copiedImage.size.width, copiedImage.size.height)
imageBounds.fill(using: .sourceAtop)
copiedImage.unlockFocus()
copiedImage.isTemplate = false
return copiedImage
}
}
无需复制:
扩展 UIImage {
func tint(with color: NSColor) -> NSImage {
self.lockFocus()
color.set()
let srcSpacePortionRect = NSRect(origin: CGPoint(), size: self.size)
srcSpacePortionRect.fill(using: .sourceAtop)
self.unlockFocus()
return self
}
}
当用户想要在明暗模式之间切换时,其他解决方案不起作用,此方法解决了:
extension NSImage {
func tint(color: NSColor) -> NSImage {
return NSImage(size: size, flipped: false) { (rect) -> Bool in
color.set()
rect.fill()
self.draw(in: rect, from: NSRect(origin: .zero, size: self.size), operation: .destinationIn, fraction: 1.0)
return true
}
}
}
请注意,如果您在 NSColor 实例上使用 .withAlphaComponent(0.5),该颜色将失去对 light/dark 模式之间切换的支持。我建议使用颜色资产来避免这个问题。
由于您的图像位于 NSImageView 中,因此以下内容应该可以正常工作(自 macOS 10.14 起可用):
let image = NSImage(named: "myImage")!
image.isTemplate = true
let imageView = NSImageView(image: image)
imageView.contentTintColor = .green
解决方案是将“contentTintColor”应用到您的 NSImageView 而不是 NSImage。
我有这样一张图片:
(呈现为模板图像)
我试过这段代码:
@IBOutlet weak var imgAdd: NSImageView!
imgAdd.layer?.backgroundColor = CGColor.white
当然这只会改变背景颜色。
有没有办法以编程方式更改此图像的颜色?
到目前为止,我已经尝试了下面的代码,但它不起作用。 (图片颜色不变。)
func tintedImage(_ image: NSImage, tint: NSColor) -> NSImage {
guard let tinted = image.copy() as? NSImage else { return image }
tinted.lockFocus()
tint.set()
let imageRect = NSRect(origin: NSZeroPoint, size: image.size)
NSRectFillUsingOperation(imageRect, .sourceAtop)
tinted.unlockFocus()
return tinted
}
imgDok.image = tintedImage(NSImage(named: "myImage")!, tint: NSColor.red)
试试这个有帮助的代码。
Swift 3
let theImageView = UIImageView(image: UIImage(named:"foo")!.withRenderingMode(.alwaysTemplate))
theImageView.tintColor = UIColor.red
在大家的帮助下我找到了解决方案:
(Swift 3)
func tintedImage(_ image: NSImage, tint: NSColor) -> NSImage {
guard let tinted = image.copy() as? NSImage else { return image }
tinted.lockFocus()
tint.set()
let imageRect = NSRect(origin: NSZeroPoint, size: image.size)
NSRectFillUsingOperation(imageRect, .sourceAtop)
tinted.unlockFocus()
return tinted
}
imgDok.image = tintedImage(NSImage(named: "myImage")!, tint: NSColor.red)
重要提示: 在界面生成器中,我必须将图像的 "render as" 设置设置为 "Default".
由于不能使用UIImage函数,可以尝试使用CoreImage(CI)。我不知道是否有更简单的版本,但这个肯定可以!
首先创建 CIImage
let image = CIImage(data: inputImage.tiffRepresentation!)
现在您可以对图像应用各种滤镜和其他东西,这是一个非常强大的工具。
CI 的文档:https://developer.apple.com/documentation/coreimage
这是一个简单的过滤器示例,您基本上是初始化一个过滤器,然后为其设置值,输出并重复。
let yourFilterName = CIFilter(name: "FilterName")
yourFilterName!.setValue(SomeInputImage, forKey: kCIInputImageKey)
yourFilterName!.setValue(10, forKey: kCIInputRadiusKey)
let yourFilterName = yourFilterName!.outputImage
现在您可以将输出转换回 NSImage。
let cgimg = context.createCGImage(yourFilterName!, from: yourFilterName!.extent)
let processedImage = NSImage(cgImage: cgimg!, size: NSSize(width: 0, height: 0))
不得不稍微修改@Ghost108 对 Xcode 9.2 的回答。
NSRectFillUsingOperation(imageRect, .sourceAtop)
至
imageRect.fill(using: .sourceAtop)
谢谢。
Swift 4
Swift 4
的更新答案请注意,此 NSImage
扩展基于 @Ghost108 和 @Taehyung_Cho 的 答案, 所以更大的功劳归于他们。
extension NSImage {
func tint(color: NSColor) -> NSImage {
let image = self.copy() as! NSImage
image.lockFocus()
color.set()
let imageRect = NSRect(origin: NSZeroPoint, size: image.size)
imageRect.fill(using: .sourceAtop)
image.unlockFocus()
return image
}
}
Swift 4个版本
extension NSImage {
func image(withTintColor tintColor: NSColor) -> NSImage {
guard isTemplate else { return self }
guard let copiedImage = self.copy() as? NSImage else { return self }
copiedImage.lockFocus()
tintColor.set()
let imageBounds = NSMakeRect(0, 0, copiedImage.size.width, copiedImage.size.height)
imageBounds.fill(using: .sourceAtop)
copiedImage.unlockFocus()
copiedImage.isTemplate = false
return copiedImage
}
}
无需复制: 扩展 UIImage {
func tint(with color: NSColor) -> NSImage {
self.lockFocus()
color.set()
let srcSpacePortionRect = NSRect(origin: CGPoint(), size: self.size)
srcSpacePortionRect.fill(using: .sourceAtop)
self.unlockFocus()
return self
}
}
当用户想要在明暗模式之间切换时,其他解决方案不起作用,此方法解决了:
extension NSImage {
func tint(color: NSColor) -> NSImage {
return NSImage(size: size, flipped: false) { (rect) -> Bool in
color.set()
rect.fill()
self.draw(in: rect, from: NSRect(origin: .zero, size: self.size), operation: .destinationIn, fraction: 1.0)
return true
}
}
}
请注意,如果您在 NSColor 实例上使用 .withAlphaComponent(0.5),该颜色将失去对 light/dark 模式之间切换的支持。我建议使用颜色资产来避免这个问题。
由于您的图像位于 NSImageView 中,因此以下内容应该可以正常工作(自 macOS 10.14 起可用):
let image = NSImage(named: "myImage")!
image.isTemplate = true
let imageView = NSImageView(image: image)
imageView.contentTintColor = .green
解决方案是将“contentTintColor”应用到您的 NSImageView 而不是 NSImage。