使用 Swift 为核心图像过滤器增加价值

Add Value to Core Image Filter using Swift

我正在使用 CIImage 向图像添加多种不同的滤镜类型。所有过滤器都可以使用它们的默认值正常工作,加上 CIPixellate 和 CICrystallize 过滤器可以使用 kCIInputScaleKey 和 kCIInputRadiusKey 值来恭敬地添加。然而,我在为 CILineOverlay 过滤器添加值时遇到了问题。我想为它提供一个特定的 inputEdgeIntensity 值。核心图像过滤器参考文档状态:

输入边缘强度: 属性类型为 CIAttributeTypeScalar 且显示名称为 Edge Intensity 的 NSNumber 对象。

默认值:1.00

但是我在任何地方都找不到有关如何使用 swift 添加此值的示例。使用此代码不起作用:

filter?.setValue(CGFloat(intensity), forKey: kCIInputIntensityKey)

任何人都可以帮助我使用 Swift 为 CILineOverlay 指定 inputEdgeIntensity 标量值的正确 format/syntax 吗?

谢谢

enum ImageEffects: String {
    case bloom = "CIBloom"
    case chrome = "CIPhotoEffectChrome"
    case comic = "CIComicEffect"
    case crystallize = "CICrystallize"
    case fade = "CIPhotoEffectFade"
    case instant = "CIPhotoEffectInstant"
    case invert = "CIColorInvert"
    case lineOverlay = "CILineOverlay"
    case mono = "CIPhotoEffectMono"
    case noir = "CIPhotoEffectNoir"
    case none = "None"
    case pixellate = "CIPixellate"
    case poster = "CIColorPosterize"
    case process = "CIPhotoEffectProcess"
    case sepia = "CISepiaTone"
    case spotColor = "CISpotColor"
    case tonal = "CIPhotoEffectTonal"
    case transfer = "CIPhotoEffectTransfer"
}

let imageEffectsArtistic: [(ImageEffects, String, Float, Bool, Float, Float)] = [
    // Effect type, effect display name,
    // default intensity setting, show slider?,
    // min slider value, max slider value
    (.none, "None", 0, false, 0, 0),
    (.comic, "Comic", 0, false, 0, 0),
    (.crystallize, "Crystallize", 30, true, 10, 100),
    (.lineOverlay, "Line", 0, false, 0, 0),
    (.pixellate, "Pixellate", 30, true, 10, 100),
    (.poster, "Poster", 0, false, 0, 0),
    (.spotColor, "Spot Color", 0, false, 0, 0)
]


if var outputImage = CIImage(image: image) {
    let extent = outputImage.extent
    let filterList = effect.rawValue.split(separator: ",")
        
    for filterItem in filterList {
        let filter = CIFilter(name: String(filterItem))
        filter?.setDefaults()
        filter?.setValue(outputImage, forKey: kCIInputImageKey)
        
        switch effect {
        case .crystallize:
            filter?.setValue(CGFloat(intensity), forKey: kCIInputRadiusKey)
        case .pixellate:
            filter?.setValue(CGFloat(intensity), forKey: kCIInputScaleKey)
        default:
            ()
        }

        if let newOutputImage = filter?.outputImage {
            outputImage = newOutputImage
        }
    }
    
    let outputCGImage = self.context.createCGImage(outputImage, from: extent)!
    imageToReturn = UIImage(cgImage: outputCGImage)
} else {
    imageToReturn = image
}

常量 kCIInputIntensityKey 映射到 "inputIntensity",但您想设置 "inputEdgeIntensity"。你应该可以这样做:

filter?.setValue(CGFloat(intensity), forKey: "inputEdgeIntensity")

(并非每个过滤器参数名称都有相应的 kCIInput... 常量。)