设置模板图像的图像颜色

时间:2017-07-11 07:52:17

标签: macos cocoa swift3 nsimageview

我有这样的图像: enter image description here

(呈现为模板图像)

我试过这段代码:

@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)

9 个答案:

答案 0 :(得分:9)

Swift 4

更新了Swift 4的答案

请注意,此NSImage扩展程序基于 @ Ghost108 @ Taehyung_Cho的答案,因此会有更大的功劳。< / p>

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
    }
}

答案 1 :(得分:6)

我找到了解决方案并得到了所有人的帮助:

(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)
界面构建器中的

重要事项我必须将&#34;渲染为&#34; 的图像设置为&#34;默认&# 34。

答案 2 :(得分:3)

不得不为Xcode 9.2修改@ Ghost108的答案。

NSRectFillUsingOperation(imageRect, .sourceAtop)

imageRect.fill(using: .sourceAtop)

感谢。

答案 3 :(得分:2)

由于您的图像在 NSImageView 中,以下应该可以正常工作(自 macOS 10.14 起可用):

let image = NSImage(named: "myImage")!
image.isTemplate = true
let imageView = NSImageView(image: image)
imageView.contentTintColor = .green

解决方案是将“contentTintColor”应用到您的 NSImageView 而不是 NSImage。

见:Documentation

答案 4 :(得分:1)

无需复制: 扩展NSImage {

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
}

}

答案 5 :(得分:1)

当用户想要在明暗模式之间切换时,其他解决方案不起作用,此方法可以解决以下问题:

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),则该颜色将失去对在明暗模式之间切换的支持。我建议使用颜色资产来避免该问题。

答案 6 :(得分:0)

由于您无法使用UIImage函数,因此可以尝试使用CoreImage(CI)。我不知道是否有一个更简单的版本,但这个肯定会工作!

首先创建CIImage

    let image = CIImage(data: inputImage.tiffRepresentation!)

现在你可以将各种滤镜和其他东西应用到图像中,这是一个非常强大的工具。

CI的文档:https://developer.apple.com/documentation/coreimage

过滤器列表:https://developer.apple.com/library/content/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html

这是一个简单的过滤器示例,您基本上初始化过滤器,然后为其设置值,输出并重复。

    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))

答案 7 :(得分:0)

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
   }
}

答案 8 :(得分:-4)

尝试这个有用的代码。

Swift 3

let theImageView = UIImageView(image: UIImage(named:"foo")!.withRenderingMode(.alwaysTemplate))
theImageView.tintColor = UIColor.red