如何解决Playground CIFilter错误消息

时间:2017-11-13 14:11:48

标签: ios swift cocoa-touch cifilter xcode9.1

下面的代码运行正常:我没有写它! : - )

我尝试使用Simon J. Gladman(https://github.com/FlexMonkey)运行一些Swift Playground代码,该代码对应于他的书“Core Image for Swift”中的第8章“Warp Kernels”。当他在Xcode 7.2中编写这段代码并且我在Xcode 9.1中运行它时,我不得不在几个地方更新它,在大多数情况下,它只是接受错误处理程序(或其所谓的)的建议。在这之后,出现了以下更严重的声音消息:

  

错误:执行被中断,原因:信号SIGABRT。   该过程一直处于被中断的位置,使用“thread> return -x”返回表达式评估之前的状态。

除了知道SIGABRT代表“信号中止”之外,我不知道这意味着什么,或者更重要的是,如何解决错误。 (我还在学习Swift和Cocoa / Cocoa Touch ......)建议不胜感激。

//: ## Barrel Distortion Warp Filter

import UIKit
import CoreImage

//: ### Warp Kernel

class CRTWarpFilter: CIFilter
{
    var inputImage: CIImage?
    var bend: CGFloat = 3.2

    let crtWarpKernel = CIWarpKernel(source:
        "kernel vec2 crtWarp(vec2 extent, float bend)" +
            "{" +
            "   vec2 coord = ((destCoord() / extent) - 0.5) * 2.0;" +

            "   coord.x *= 1.0 + pow((abs(coord.y) / bend), 2.0);" +
            "   coord.y *= 1.0 + pow((abs(coord.x) / bend), 2.0);" +

            "   coord  = ((coord / 2.0) + 0.5) * extent;" +

            "   return coord;" +
        "}"
    )

    override var outputImage: CIImage!
    {
        if let inputImage = inputImage, let crtWarpKernel = crtWarpKernel
        {
            let arguments = [CIVector(x: inputImage.extent.size.width,
                                      y: inputImage.extent.size.height),
                             bend] as [Any]

            let extent = inputImage.extent

            return crtWarpKernel.apply(extent: extent,
                                       roiCallback:
                                           {(index, rect) in return rect},
                                       image: inputImage,
                                       arguments: arguments)
        }
        return nil
    }
}

let ciContext = CIContext()

func imageFromCIImage(source: CIImage) -> UIImage
{
    let cgImage = ciContext.createCGImage(source, from: source.extent)

    return UIImage(cgImage: cgImage!)
}

//: ### Swift Implementation of barrel warp kernel

//: `x` and `y` are pixel coordinates
let x = 65.0
let y = 55.0

//: `width` and `height` are extent
let width = 900.0
let height = 300.0

//: `crtWarpKernel` mechanics in Swift
var coordX = ((x / width) - 0.5) * 2.0
var coordY = ((y / height) - 0.5) * 2.0

coordX *= 1 + pow((abs(coordY) / 3.2), 2.0)
coordY *= 1 + pow((abs(coordX) / 3.2), 2.0)

coordX  = ((coordX / 2.0) + 0.5) * width
coordY  = ((coordY / 2.0) + 0.5) * height

// ----

let backgroundImage = CIFilter(name: "CICheckerboardGenerator",
                               withInputParameters: [
                                "inputColor0":
                                    CIColor(red: 0.1, green: 0.1, blue: 0.1),
                                "inputColor1":
                                    CIColor(red: 0.15, green: 0.15, blue: 0.15),
                                "inputCenter": CIVector(x: 0, y: 0),
                                "inputWidth": 50])!
    .outputImage!.cropped(to: CGRect(x: 1, y: 1,
                                     width: width - 2,
                                     height: height - 2))
    .composited(over: CIImage(color: CIColor(red: 0, green: 0, blue: 0)))
    .cropped(to: CGRect(origin: CGPoint.zero,
                        size: CGSize(width: width, height: height)))

let blueBox = CIImage(color: CIColor(red: 0.5, green: 0.5, blue: 1, alpha: 0.7))
    .cropped(to: CGRect(origin: CGPoint(x: coordX - 5, y: coordY - 5),
                        size: CGSize(width: 10, height: 10)))

let redBox = CIImage(color: CIColor(red: 1, green: 0, blue: 0, alpha: 0.7))
    .cropped(to: CGRect(origin: CGPoint(x: x - 5, y: y - 5),
                        size: CGSize(width: 10, height: 10)))

let warpFilter = CRTWarpFilter()

warpFilter.inputImage = backgroundImage

let composite = CIFilter(name: "CIAdditionCompositing",
                         withInputParameters: [
                            kCIInputBackgroundImageKey: warpFilter.outputImage,
                            kCIInputImageKey: blueBox])!
    .outputImage!
    .applyingFilter("CIAdditionCompositing",
                    parameters: [kCIInputBackgroundImageKey: redBox])

let result = composite

1 个答案:

答案 0 :(得分:1)

游乐场不喜欢inputImage未声明为@objc。如果您更改此设置:

class CRTWarpFilter: CIFilter
{
    var inputImage: CIImage?

对此:

class CRTWarpFilter: CIFilter
{
    @objc var inputImage: CIImage?

一切正常。

这是您的代码更新为Xcode 11Swift 5

//: ## Barrel Distortion Warp Filter

import UIKit
import CoreImage

//: ### Warp Kernel

class CRTWarpFilter: CIFilter
{
    @objc var inputImage: CIImage?
    var bend: CGFloat = 3.2

    let crtWarpKernel = CIWarpKernel(source: """
        kernel vec2 crtWarp(vec2 extent, float bend)
        {
           vec2 coord = ((destCoord() / extent) - 0.5) * 2.0;

           coord.x *= 1.0 + pow((abs(coord.y) / bend), 2.0);
           coord.y *= 1.0 + pow((abs(coord.x) / bend), 2.0);

           coord  = ((coord / 2.0) + 0.5) * extent;

           return coord;
        }
    """)

    override var outputImage: CIImage?
    {
        if let inputImage = inputImage, let crtWarpKernel = crtWarpKernel
        {
            let arguments = [CIVector(x: inputImage.extent.size.width,
                                      y: inputImage.extent.size.height),
                             bend] as [Any]

            let extent = inputImage.extent

            return crtWarpKernel.apply(extent: extent,
                                       roiCallback:
                {(index, rect) in return rect},
                                       image: inputImage,
                                       arguments: arguments)
        }
        return nil
    }
}

let ciContext = CIContext()

func imageFromCIImage(source: CIImage) -> UIImage
{
    let cgImage = ciContext.createCGImage(source, from: source.extent)

    return UIImage(cgImage: cgImage!)
}

//: ### Swift Implementation of barrel warp kernel

//: `x` and `y` are pixel coordinates
let x = 65.0
let y = 55.0

//: `width` and `height` are extent
let width = 900.0
let height = 300.0

//: `crtWarpKernel` mechanics in Swift
var coordX = ((x / width) - 0.5) * 2.0
var coordY = ((y / height) - 0.5) * 2.0

coordX *= 1 + pow((abs(coordY) / 3.2), 2.0)
coordY *= 1 + pow((abs(coordX) / 3.2), 2.0)

coordX  = ((coordX / 2.0) + 0.5) * width
coordY  = ((coordY / 2.0) + 0.5) * height

// ----

let backgroundImage = CIFilter(name: "CICheckerboardGenerator",
                               parameters: [
                                "inputColor0":
                                    CIColor(red: 0.1, green: 0.1, blue: 0.1),
                                "inputColor1":
                                    CIColor(red: 0.15, green: 0.15, blue: 0.15),
                                "inputCenter": CIVector(x: 0, y: 0),
                                "inputWidth": 50])!
    .outputImage!.cropped(to: CGRect(x: 1, y: 1,
                                     width: width - 2,
                                     height: height - 2))
    .composited(over: CIImage(color: CIColor(red: 0, green: 0, blue: 0)))
    .cropped(to: CGRect(origin: CGPoint.zero,
                        size: CGSize(width: width, height: height)))

let blueBox = CIImage(color: CIColor(red: 0.5, green: 0.5, blue: 1, alpha: 0.7))
    .cropped(to: CGRect(origin: CGPoint(x: coordX - 5, y: coordY - 5),
                        size: CGSize(width: 10, height: 10)))

let redBox = CIImage(color: CIColor(red: 1, green: 0, blue: 0, alpha: 0.7))
    .cropped(to: CGRect(origin: CGPoint(x: x - 5, y: y - 5),
                        size: CGSize(width: 10, height: 10)))

let warpFilter = CRTWarpFilter()
warpFilter.inputImage = backgroundImage

let composite = CIFilter(name: "CIAdditionCompositing",
                         parameters: [
                            kCIInputBackgroundImageKey: warpFilter.outputImage,
                            kCIInputImageKey: blueBox])!
    .outputImage!
    .applyingFilter("CIAdditionCompositing",
                    parameters: [kCIInputBackgroundImageKey: redBox])

let result = composite