创建透明渐变并将其用作 SpriteKit 中的 alpha 遮罩

2024-04-24

我正在尝试制作渐变并将其用作 alpha 蒙版。现在,我能够制作与此类似的图像(从黑色到透明):

这是我用来实现这一切的代码:

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
    }

对我来说,这种方法非常完美,因为我在代码中仅创建一次掩码(创建 GUI 元素时),因此性能根本不受影响。

问题是我实际上需要一个结果图像(渐变纹理)看起来像这样(渐变应该具有固定的高度,但黑色区域的大小可能会有所不同):

Because CILinearGradient过滤器没有inputImage参数,我无法将两个过滤器依次链接起来。但我必须创建一个图像,并应用一个过滤器,然后创建另一个图像,并应用一个新的过滤器。

我就像上面描述的那样解决了这个问题。此外,我还必须分三个步骤扩展一个过程(创建上部渐变、创建中间黑色区域和创建下部渐变),然后将所有这些组合成一个图像。

我想知道有什么关于CI线性渐变 https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CILinearGradient过滤器我不知道?也许有一种更简单的方法来解决这个问题并制作复杂的渐变?

请注意,我正在使用 SpriteKit,并且使用 CAGradientLayer 解决此问题并不是我想要的方法。


我不确定 Core Image 是适合这里工作的工具 - 你可能最好使用CGGradient绘制图像的函数。


旁白:您所要求的在 CoreImage 中是可能的,但很麻烦。可以类比一下,作为 Photoshop 或其他常见图形软件的用户创建这些图像的操作...CoreImage 方式将如下所示:

  1. 为上面的渐变创建一个图层,用渐变填充整个画布,然后将图层转换到正确的位置和大小
  2. 为中间黑色部分创建一个图层,将整个画布填充为黑色,并将图层变换到合适的位置和大小
  3. 同上 #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)!
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建透明渐变并将其用作 SpriteKit 中的 alpha 遮罩 的相关文章

随机推荐