Get and change hue of SKSpriteNode's SKColor(HSBA)?

437 views Asked by At

A SKSpriteNode's SKColor has a way to be created with Hue, Saturation, Brightness & Alpha:

    let myColor = SKColor(hue: 0.5, saturation: 1, brightness: 1, alpha: 1)
 mySprite.color = myColor

How do I get at the hue of a SKSpriteNode and make a change to it? eg, divide it by 2.

2

There are 2 answers

0
Alessandro Ornano On BEST ANSWER

An SKSpriteNode is a node that draws a texture (optionally blended with a color), an image, a colored square. So, this is it's nature.

When you make an SKSpriteNode, you have an instance property that represent the texture used to draw the sprite called also texture

Since iOS 9.x, we are able to retrieve an image from a texture following the code below. In this example I call my SKSpriteNode as spriteBg:

let spriteBg = SKSpriteNode.init(texture: SKTexture.init(imageNamed: "myImage.png"))

if let txt = spriteBg.texture {
            if #available(iOS 9.0, *) {
                let image : UIImage = UIImage.init(cgImage:txt.cgImage())
            } else {
                // Fallback on earlier versions and forgot this code..
            }
}

Following this interesting answer, we can translate it to a more confortable Swift 3.0 version:

func imageWith(source: UIImage, rotatedByHue: CGFloat) -> UIImage {
        // Create a Core Image version of the image.
        let sourceCore = CIImage(cgImage: source.cgImage!)
        // Apply a CIHueAdjust filter
        guard let hueAdjust = CIFilter(name: "CIHueAdjust") else { return source }
        hueAdjust.setDefaults()
        hueAdjust.setValue(sourceCore, forKey: "inputImage")
        hueAdjust.setValue(CGFloat(rotatedByHue), forKey: "inputAngle")
        let resultCore  = hueAdjust.value(forKey: "outputImage") as! CIImage!
        let context = CIContext(options: nil)
        let resultRef = context.createCGImage(resultCore!, from: resultCore!.extent)
        let result = UIImage(cgImage: resultRef!)
        return result
}

So, finally with the previous code we can do:

if let txt = spriteBg.texture {
            if #available(iOS 9.0, *) {
                let image : UIImage = UIImage.init(cgImage:txt.cgImage())
                let changedImage = imageWith(source: image, rotatedByHue: 0.5)
                spriteBg.texture = SKTexture(image: changedImage)
            } else {
                // Fallback on earlier versions or bought a new iphone
            }
}
2
claassenApps On

I'm not in a place to be able to test this right now, but looking at the UIColor documentation (UIColor and SKColor are basically the same thing), you should be able to use the .getHue(...) function retrieve the color's components, make changes to it, then set the SKSpriteNode's color property to the new value. the .getHue(...) function "Returns the components that make up the color in the HSB color space."

https://developer.apple.com/reference/uikit/uicolor/1621949-gethue