Create a transparent gradient and use it as an alpha mask in SpriteKit

I am trying to make a gradient and use it as an alpha mask. Right now, I can make an image like this (black to transparent):

gradient

This is the code that I use to create all of this:

private func createImage(width: CGFloat, height: CGFloat) -> CGImageRef?{

        if let ciFilter = CIFilter(name: "CILinearGradient"){

            let ciContext = CIContext()

            ciFilter.setDefaults()

            let startColor  = CIColor(red: 0, green: 0, blue: 0, alpha: 0)
            let endColor    = CIColor(red: 0, green: 0, blue: 0, alpha: 1)

            let startVector = CIVector(x: 0, y: height-10)
            let endVector   = CIVector(x: 0, y: height-22)

            ciFilter.setValue(startColor,   forKey: "inputColor0")
            ciFilter.setValue(endColor,     forKey: "inputColor1")
            ciFilter.setValue(startVector,  forKey: "inputPoint0")
            ciFilter.setValue(endVector,    forKey: "inputPoint1")



            if let outputImage = ciFilter.outputImage {

                let  cgImage:CGImageRef = ciContext.createCGImage(outputImage, fromRect: CGRect(x: 0, y: 0, width: width, height: height))

                return  cgImage

            }

        }

        return nil
    }

For me, this method works perfectly, because I only create a mask in my code (when the GUI element is created), so the performance does not change at all.

The thing is, I really need to get the resulting image (gradient texture) so that it looks (gradients should have a fixed height, but the size of the black area can vary):

desired appearance of the gradient texture

CILinearGradient inputImage, . , .

, . ( , , ), .

, - CILinearGradient , ? , ?

, SpriteKit CAGradientLayer, , .

+4
1

, Core Image - - , , CGGradient .


: , , , CoreImage. , Photoshop ... CoreImage :

  • , .
  • , .
  • Ditto # 1, .

, ...

gradient    -> transform -\
                           }-> composite -\
solid color -> transform -/                \
                                            }-> composite
gradient    -> transform ————————————————--/

.

, Photoshop / ... , CoreGraphics, .


, CG-? - ...

func createImage(width: CGFloat, _ height: CGFloat) -> CGImage {

    let gradientOffset: CGFloat = 10 // white at bottom and top before/after gradient
    let gradientLength: CGFloat = 12 // height of gradient region

    // create colors and gradient for drawing with
    let space = CGColorSpaceCreateDeviceRGB()
    let startColor = UIColor.whiteColor().CGColor
    let endColor = UIColor.blackColor().CGColor
    let colors: CFArray = [startColor, endColor]
    let gradient = CGGradientCreateWithColors(space, colors, [0,1])

    // start an image context
    UIGraphicsBeginImageContext(CGSize(width: width, height: height))
    defer { UIGraphicsEndImageContext() }
    let context = UIGraphicsGetCurrentContext()

    // fill the whole thing with white (that'll show through at the ends when done)
    CGContextSetFillColorWithColor(context, startColor)
    CGContextFillRect(context, CGRect(x: 0, y: 0, width: width, height: height))

    // draw top gradient
    CGContextDrawLinearGradient(context, gradient, CGPoint(x: 0, y: gradientOffset), CGPoint(x: 0, y: gradientOffset + gradientLength), [])

    // fill solid black middle
    CGContextSetFillColorWithColor(context, endColor)
    CGContextFillRect(context, CGRect(x: 0, y: gradientOffset + gradientLength, width: width, height: height - 2 * gradientOffset - 2 * gradientLength))

    // draw bottom gradient
    CGContextDrawLinearGradient(context, gradient, CGPoint(x: 0, y: height - gradientOffset), CGPoint(x: 0, y: height - gradientOffset - gradientLength), [])

    return CGBitmapContextCreateImage(context)!
}
+3

Source: https://habr.com/ru/post/1621327/


All Articles