From bb11cba5b6a327d8f8ca7505edc975031092bb41 Mon Sep 17 00:00:00 2001 From: Brad Larson Date: Sun, 18 Feb 2024 12:23:10 -0600 Subject: [PATCH] Expand formatting to tests and examples, ease up some of the lint checks. --- .github/workflows/lint.yml | 2 +- .swift-format.json | 10 +- Sources/GPUImage/BasicOperation.swift | 3 +- Sources/GPUImage/Operations/BoxBlur.swift | 3 +- Sources/GPUImage/PictureOutput.swift | 12 +- Tests/GPUImageTests/MatrixTests.swift | 5 +- .../FilterShowcase/AppDelegate.swift | 6 +- .../FilterShowcase/FilterOperationTypes.swift | 44 +- .../FilterShowcase/FilterOperations.swift | 1781 +++++++++-------- .../FilterShowcaseWindowController.swift | 96 +- .../SimpleImageFilter/AppDelegate.swift | 27 +- .../SimpleMovieFilter/AppDelegate.swift | 15 +- .../SimpleVideoFilter/AppDelegate.swift | 20 +- .../SimpleVideoRecorder/AppDelegate.swift | 35 +- .../FilterShowcaseSwift/AppDelegate.swift | 8 +- .../FilterDisplayViewController.swift | 56 +- .../FilterListViewController.swift | 10 +- .../SimpleImageFilter/AppDelegate.swift | 6 +- .../SimpleImageFilter/ViewController.swift | 28 +- .../SimpleMovieFilter/AppDelegate.swift | 6 +- .../SimpleMovieFilter/ViewController.swift | 27 +- .../SimpleVideoFilter/AppDelegate.swift | 8 +- .../SimpleVideoFilter/ViewController.swift | 17 +- .../SimpleVideoRecorder/AppDelegate.swift | 7 +- .../SimpleVideoRecorder/ViewController.swift | 38 +- 25 files changed, 1152 insertions(+), 1118 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ef573e68..c8ed485a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,4 +17,4 @@ jobs: - name: Install run: brew install swift-format - name: Run linting - run: swift-format lint --recursive --parallel --strict --configuration .swift-format.json Package.swift Sources \ No newline at end of file + run: swift-format lint --recursive --parallel --strict --configuration .swift-format.json Package.swift Sources Tests examples diff --git a/.swift-format.json b/.swift-format.json index fd6d4e91..59165e6b 100644 --- a/.swift-format.json +++ b/.swift-format.json @@ -24,7 +24,7 @@ "rules" : { "AllPublicDeclarationsHaveDocumentation" : false, "AlwaysUseLiteralForEmptyCollectionInit" : false, - "AlwaysUseLowerCamelCase" : true, + "AlwaysUseLowerCamelCase" : false, "AmbiguousTrailingClosureOverload" : true, "BeginDocumentationCommentWithOneLineSummary" : false, "DoNotUseSemicolons" : true, @@ -38,7 +38,7 @@ "NeverUseImplicitlyUnwrappedOptionals" : false, "NoAccessLevelOnExtensionDeclaration" : true, "NoAssignmentInExpressions" : true, - "NoBlockComments" : true, + "NoBlockComments" : false, "NoCasesWithOnlyFallthrough" : true, "NoEmptyTrailingClosureParentheses" : true, "NoLabelsInCasePatterns" : true, @@ -53,9 +53,9 @@ "OrderedImports" : true, "ReplaceForEachWithForLoop" : true, "ReturnVoidInsteadOfEmptyTuple" : true, - "TypeNamesShouldBeCapitalized" : true, + "TypeNamesShouldBeCapitalized" : false, "UseEarlyExits" : false, - "UseLetInEveryBoundCaseVariable" : true, + "UseLetInEveryBoundCaseVariable" : false, "UseShorthandTypeNames" : true, "UseSingleLinePropertyGetter" : true, "UseSynthesizedInitializer" : true, @@ -66,4 +66,4 @@ "spacesAroundRangeFormationOperators" : false, "tabWidth" : 4, "version" : 1 -} \ No newline at end of file +} diff --git a/Sources/GPUImage/BasicOperation.swift b/Sources/GPUImage/BasicOperation.swift index 286c80e9..783655d4 100644 --- a/Sources/GPUImage/BasicOperation.swift +++ b/Sources/GPUImage/BasicOperation.swift @@ -91,7 +91,8 @@ open class BasicOperation: ImageProcessingOperation { width: outputWidth, height: outputHeight, timingStyle: firstInputTexture.timingStyle ) - guard !activatePassthroughOnNextFrame else { // Use this to allow a bootstrap of cyclical processing, like with a low pass filter + guard !activatePassthroughOnNextFrame else { + // Use this to allow a bootstrap of cyclical processing, like with a low pass filter. activatePassthroughOnNextFrame = false // TODO: Render rotated passthrough image here diff --git a/Sources/GPUImage/Operations/BoxBlur.swift b/Sources/GPUImage/Operations/BoxBlur.swift index b8cd3096..efa2fe17 100644 --- a/Sources/GPUImage/Operations/BoxBlur.swift +++ b/Sources/GPUImage/Operations/BoxBlur.swift @@ -8,7 +8,8 @@ public class BoxBlur: BasicOperation { public var blurRadiusInPixels: Float = 2.0 { didSet { if self.useMetalPerformanceShaders, #available(iOS 9, macOS 10.13, *) { - let kernelSize = roundToOdd(blurRadiusInPixels) // MPS box blur kernels need to be odd + // MPS box blur kernels need to be odd. + let kernelSize = roundToOdd(blurRadiusInPixels) internalMPSImageBox = MPSImageBox( device: sharedMetalRenderingDevice.device, kernelWidth: kernelSize, kernelHeight: kernelSize) diff --git a/Sources/GPUImage/PictureOutput.swift b/Sources/GPUImage/PictureOutput.swift index 72b2c7b8..eff2d07c 100644 --- a/Sources/GPUImage/PictureOutput.swift +++ b/Sources/GPUImage/PictureOutput.swift @@ -34,7 +34,9 @@ public class PictureOutput: ImageConsumer { public func saveNextFrameToURL(_ url: URL, format: PictureFileFormat) { onlyCaptureNextFrame = true encodedImageFormat = format - self.url = url // Create an intentional short-term retain cycle to prevent deallocation before next frame is captured + self.url = url + // Create an intentional short-term retain cycle to prevent deallocation + // before next frame is captured. encodedImageAvailableCallback = { imageData in do { try imageData.write(to: self.url, options: .atomic) @@ -75,8 +77,12 @@ public class PictureOutput: ImageConsumer { #if canImport(UIKit) let image = UIImage(cgImage: cgImageFromBytes, scale: 1.0, orientation: .up) switch encodedImageFormat { - case .png: imageData = image.pngData()! // TODO: Better error handling here - case .jpeg: imageData = image.jpegData(compressionQuality: 0.8)! // TODO: Be able to set image quality + case .png: + // TODO: Better error handling here. + imageData = image.pngData()! + case .jpeg: + // TODO: Be able to set image quality. + imageData = image.jpegData(compressionQuality: 0.8)! } #else let bitmapRepresentation = NSBitmapImageRep(cgImage: cgImageFromBytes) diff --git a/Tests/GPUImageTests/MatrixTests.swift b/Tests/GPUImageTests/MatrixTests.swift index e4bb645d..5d1bdfe0 100644 --- a/Tests/GPUImageTests/MatrixTests.swift +++ b/Tests/GPUImageTests/MatrixTests.swift @@ -1,4 +1,5 @@ import XCTest + @testable import GPUImage final class MatrixTests: XCTestCase { @@ -6,9 +7,9 @@ final class MatrixTests: XCTestCase { let newMatrix = Matrix3x3(rowMajorValues: [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, - 7.0, 8.0, 9.0 + 7.0, 8.0, 9.0, ]) - + XCTAssertEqual(newMatrix.m11, 1.0) XCTAssertEqual(newMatrix.m23, 6.0) XCTAssertEqual(newMatrix.m32, 8.0) diff --git a/examples/Mac/FilterShowcase/FilterShowcase/AppDelegate.swift b/examples/Mac/FilterShowcase/FilterShowcase/AppDelegate.swift index c096418f..e76b1080 100755 --- a/examples/Mac/FilterShowcase/FilterShowcase/AppDelegate.swift +++ b/examples/Mac/FilterShowcase/FilterShowcase/AppDelegate.swift @@ -5,11 +5,11 @@ class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow! - var windowController:FilterShowcaseWindowController? + var windowController: FilterShowcaseWindowController? func applicationDidFinishLaunching(_ aNotification: Notification) { - self.windowController = FilterShowcaseWindowController(windowNibName:NSNib.Name(rawValue: "FilterShowcaseWindowController")) + self.windowController = FilterShowcaseWindowController( + windowNibName: NSNib.Name(rawValue: "FilterShowcaseWindowController")) self.windowController?.showWindow(self) } } - diff --git a/examples/Mac/FilterShowcase/FilterShowcase/FilterOperationTypes.swift b/examples/Mac/FilterShowcase/FilterShowcase/FilterOperationTypes.swift index 66626f21..3c0df99a 100755 --- a/examples/Mac/FilterShowcase/FilterShowcase/FilterOperationTypes.swift +++ b/examples/Mac/FilterShowcase/FilterShowcase/FilterOperationTypes.swift @@ -3,7 +3,7 @@ import GPUImage enum FilterSliderSetting { case disabled - case enabled(minimumValue:Float, maximumValue:Float, initialValue:Float) + case enabled(minimumValue: Float, maximumValue: Float, initialValue: Float) } typealias FilterSetupFunction = (Camera, ImageProcessingOperation, RenderView) -> ImageSource? @@ -11,33 +11,38 @@ typealias FilterSetupFunction = (Camera, ImageProcessingOperation, RenderView) - enum FilterOperationType { case singleInput case blend - case custom(filterSetupFunction:FilterSetupFunction) + case custom(filterSetupFunction: FilterSetupFunction) } protocol FilterOperationInterface { var filter: ImageProcessingOperation { get } - var secondInput:ImageSource? { get } + var secondInput: ImageSource? { get } var listName: String { get } var titleName: String { get } - var sliderConfiguration: FilterSliderSetting { get } - var filterOperationType: FilterOperationType { get } + var sliderConfiguration: FilterSliderSetting { get } + var filterOperationType: FilterOperationType { get } - func configureCustomFilter(_ secondInput:ImageSource?) - func updateBasedOnSliderValue(_ sliderValue:Float) + func configureCustomFilter(_ secondInput: ImageSource?) + func updateBasedOnSliderValue(_ sliderValue: Float) } class FilterOperation: FilterOperationInterface { - lazy var internalFilter:FilterClass = { + lazy var internalFilter: FilterClass = { return self.filterCreationFunction() }() - let filterCreationFunction:() -> FilterClass - var secondInput:ImageSource? - let listName:String - let titleName:String - let sliderConfiguration:FilterSliderSetting - let filterOperationType:FilterOperationType - let sliderUpdateCallback: ((FilterClass, Float) -> ())? - init(filter:@escaping () -> FilterClass, listName: String, titleName: String, sliderConfiguration: FilterSliderSetting, sliderUpdateCallback:((FilterClass, Float) -> ())?, filterOperationType: FilterOperationType) { + let filterCreationFunction: () -> FilterClass + var secondInput: ImageSource? + let listName: String + let titleName: String + let sliderConfiguration: FilterSliderSetting + let filterOperationType: FilterOperationType + let sliderUpdateCallback: ((FilterClass, Float) -> Void)? + init( + filter: @escaping () -> FilterClass, listName: String, titleName: String, + sliderConfiguration: FilterSliderSetting, + sliderUpdateCallback: ((FilterClass, Float) -> Void)?, + filterOperationType: FilterOperationType + ) { self.listName = listName self.titleName = titleName self.sliderConfiguration = sliderConfiguration @@ -45,17 +50,16 @@ class FilterOperation: FilterOpe self.sliderUpdateCallback = sliderUpdateCallback self.filterCreationFunction = filter } - + var filter: ImageProcessingOperation { return internalFilter } - func configureCustomFilter(_ secondInput:ImageSource?) { + func configureCustomFilter(_ secondInput: ImageSource?) { self.secondInput = secondInput } - func updateBasedOnSliderValue(_ sliderValue:Float) { + func updateBasedOnSliderValue(_ sliderValue: Float) { sliderUpdateCallback?(internalFilter, sliderValue) } } - diff --git a/examples/Mac/FilterShowcase/FilterShowcase/FilterOperations.swift b/examples/Mac/FilterShowcase/FilterShowcase/FilterOperations.swift index d0218fd6..6fae5a66 100755 --- a/examples/Mac/FilterShowcase/FilterShowcase/FilterOperations.swift +++ b/examples/Mac/FilterShowcase/FilterShowcase/FilterOperations.swift @@ -1,1181 +1,1184 @@ import GPUImage import QuartzCore -let filterOperations: Array = [ - FilterOperation ( - filter:{SaturationAdjustment()}, - listName:"Saturation", - titleName:"Saturation", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:2.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in +let filterOperations: [FilterOperationInterface] = [ + FilterOperation( + filter: { SaturationAdjustment() }, + listName: "Saturation", + titleName: "Saturation", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 2.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.saturation = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{ContrastAdjustment()}, - listName:"Contrast", - titleName:"Contrast", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:4.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { ContrastAdjustment() }, + listName: "Contrast", + titleName: "Contrast", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 4.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.contrast = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{BrightnessAdjustment()}, - listName:"Brightness", - titleName:"Brightness", - sliderConfiguration:.enabled(minimumValue:-1.0, maximumValue:1.0, initialValue:0.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { BrightnessAdjustment() }, + listName: "Brightness", + titleName: "Brightness", + sliderConfiguration: .enabled(minimumValue: -1.0, maximumValue: 1.0, initialValue: 0.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.brightness = sliderValue }, - filterOperationType:.singleInput - ), - FilterOperation( - filter:{LevelsAdjustment()}, - listName:"Levels", - titleName:"Levels", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.0), - sliderUpdateCallback: {(filter, sliderValue) in - filter.minimum = Color(red:Float(sliderValue), green:Float(sliderValue), blue:Float(sliderValue)) - filter.middle = Color(red:1.0, green:1.0, blue:1.0) - filter.maximum = Color(red:1.0, green:1.0, blue:1.0) - filter.minOutput = Color(red:0.0, green:0.0, blue:0.0) - filter.maxOutput = Color(red:1.0, green:1.0, blue:1.0) + filterOperationType: .singleInput + ), + FilterOperation( + filter: { LevelsAdjustment() }, + listName: "Levels", + titleName: "Levels", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.0), + sliderUpdateCallback: { (filter, sliderValue) in + filter.minimum = Color( + red: Float(sliderValue), green: Float(sliderValue), blue: Float(sliderValue)) + filter.middle = Color(red: 1.0, green: 1.0, blue: 1.0) + filter.maximum = Color(red: 1.0, green: 1.0, blue: 1.0) + filter.minOutput = Color(red: 0.0, green: 0.0, blue: 0.0) + filter.maxOutput = Color(red: 1.0, green: 1.0, blue: 1.0) }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{ExposureAdjustment()}, - listName:"Exposure", - titleName:"Exposure", - sliderConfiguration:.enabled(minimumValue:-4.0, maximumValue:4.0, initialValue:0.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { ExposureAdjustment() }, + listName: "Exposure", + titleName: "Exposure", + sliderConfiguration: .enabled(minimumValue: -4.0, maximumValue: 4.0, initialValue: 0.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.exposure = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{RGBAdjustment()}, - listName:"RGB", - titleName:"RGB", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:2.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { RGBAdjustment() }, + listName: "RGB", + titleName: "RGB", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 2.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.green = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{HueAdjustment()}, - listName:"Hue", - titleName:"Hue", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:360.0, initialValue:90.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { HueAdjustment() }, + listName: "Hue", + titleName: "Hue", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 360.0, initialValue: 90.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.hue = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{WhiteBalance()}, - listName:"White balance", - titleName:"White Balance", - sliderConfiguration:.enabled(minimumValue:2500.0, maximumValue:7500.0, initialValue:5000.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { WhiteBalance() }, + listName: "White balance", + titleName: "White Balance", + sliderConfiguration: .enabled( + minimumValue: 2500.0, maximumValue: 7500.0, initialValue: 5000.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.temperature = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{MonochromeFilter()}, - listName:"Monochrome", - titleName:"Monochrome", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { MonochromeFilter() }, + listName: "Monochrome", + titleName: "Monochrome", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.intensity = sliderValue }, - filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + filterOperationType: .custom(filterSetupFunction: { (camera, filter, outputView) in let castFilter = filter as! MonochromeFilter camera --> castFilter --> outputView - castFilter.color = Color(red:0.0, green:0.0, blue:1.0, alpha:1.0) + castFilter.color = Color(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0) return nil }) ), FilterOperation( - filter:{FalseColor()}, - listName:"False color", - titleName:"False Color", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.singleInput - ), -// FilterOperation( -// filter:{Sharpen()}, -// listName:"Sharpen", -// titleName:"Sharpen", -// sliderConfiguration:.enabled(minimumValue:-1.0, maximumValue:4.0, initialValue:0.0), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.sharpness = sliderValue -// }, -// filterOperationType:.singleInput -// ), -// FilterOperation( -// filter:{UnsharpMask()}, -// listName:"Unsharp mask", -// titleName:"Unsharp Mask", -// sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:5.0, initialValue:1.0), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.intensity = sliderValue -// }, -// filterOperationType:.singleInput -// ), -// FilterOperation( -// filter:{TransformOperation()}, -// listName:"Transform (2-D)", -// titleName:"Transform (2-D)", -// sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:6.28, initialValue:0.75), -// sliderUpdateCallback:{(filter, sliderValue) in -// filter.transform = Matrix4x4(CGAffineTransform(rotationAngle:CGFloat(sliderValue))) -// }, -// filterOperationType:.singleInput -// ), -// FilterOperation( -// filter:{TransformOperation()}, -// listName:"Transform (3-D)", -// titleName:"Transform (3-D)", -// sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:6.28, initialValue:0.75), -// sliderUpdateCallback:{(filter, sliderValue) in -// var perspectiveTransform = CATransform3DIdentity -// perspectiveTransform.m34 = 0.4 -// perspectiveTransform.m33 = 0.4 -// perspectiveTransform = CATransform3DScale(perspectiveTransform, 0.75, 0.75, 0.75) -// perspectiveTransform = CATransform3DRotate(perspectiveTransform, CGFloat(sliderValue), 0.0, 1.0, 0.0) -// filter.transform = Matrix4x4(perspectiveTransform) -// }, -// filterOperationType:.singleInput -// ), -// FilterOperation( -// filter:{Crop()}, -// listName:"Crop", -// titleName:"Crop", -// sliderConfiguration:.enabled(minimumValue:240.0, maximumValue:480.0, initialValue:240.0), -// sliderUpdateCallback:{(filter, sliderValue) in -// filter.cropSizeInPixels = Size(width:480.0, height:sliderValue) -// }, -// filterOperationType:.singleInput -// ), -// FilterOperation( -// filter:{Luminance()}, -// listName:"Masking", -// titleName:"Mask Example", -// sliderConfiguration:.disabled, -// sliderUpdateCallback: nil, -// filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in -// let castFilter = filter as! Luminance -// let maskImage = PictureInput(imageName:"Mask.png") -// castFilter.drawUnmodifiedImageOutsideOfMask = false -// castFilter.mask = maskImage -// maskImage.processImage() -// camera --> castFilter --> outputView -// return nil -// }) -// ), - FilterOperation( - filter:{GammaAdjustment()}, - listName:"Gamma", - titleName:"Gamma", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:3.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { FalseColor() }, + listName: "False color", + titleName: "False Color", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .singleInput + ), + // FilterOperation( + // filter:{Sharpen()}, + // listName:"Sharpen", + // titleName:"Sharpen", + // sliderConfiguration:.enabled(minimumValue:-1.0, maximumValue:4.0, initialValue:0.0), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.sharpness = sliderValue + // }, + // filterOperationType:.singleInput + // ), + // FilterOperation( + // filter:{UnsharpMask()}, + // listName:"Unsharp mask", + // titleName:"Unsharp Mask", + // sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:5.0, initialValue:1.0), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.intensity = sliderValue + // }, + // filterOperationType:.singleInput + // ), + // FilterOperation( + // filter:{TransformOperation()}, + // listName:"Transform (2-D)", + // titleName:"Transform (2-D)", + // sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:6.28, initialValue:0.75), + // sliderUpdateCallback:{(filter, sliderValue) in + // filter.transform = Matrix4x4(CGAffineTransform(rotationAngle:CGFloat(sliderValue))) + // }, + // filterOperationType:.singleInput + // ), + // FilterOperation( + // filter:{TransformOperation()}, + // listName:"Transform (3-D)", + // titleName:"Transform (3-D)", + // sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:6.28, initialValue:0.75), + // sliderUpdateCallback:{(filter, sliderValue) in + // var perspectiveTransform = CATransform3DIdentity + // perspectiveTransform.m34 = 0.4 + // perspectiveTransform.m33 = 0.4 + // perspectiveTransform = CATransform3DScale(perspectiveTransform, 0.75, 0.75, 0.75) + // perspectiveTransform = CATransform3DRotate(perspectiveTransform, CGFloat(sliderValue), 0.0, 1.0, 0.0) + // filter.transform = Matrix4x4(perspectiveTransform) + // }, + // filterOperationType:.singleInput + // ), + // FilterOperation( + // filter:{Crop()}, + // listName:"Crop", + // titleName:"Crop", + // sliderConfiguration:.enabled(minimumValue:240.0, maximumValue:480.0, initialValue:240.0), + // sliderUpdateCallback:{(filter, sliderValue) in + // filter.cropSizeInPixels = Size(width:480.0, height:sliderValue) + // }, + // filterOperationType:.singleInput + // ), + // FilterOperation( + // filter:{Luminance()}, + // listName:"Masking", + // titleName:"Mask Example", + // sliderConfiguration:.disabled, + // sliderUpdateCallback: nil, + // filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + // let castFilter = filter as! Luminance + // let maskImage = PictureInput(imageName:"Mask.png") + // castFilter.drawUnmodifiedImageOutsideOfMask = false + // castFilter.mask = maskImage + // maskImage.processImage() + // camera --> castFilter --> outputView + // return nil + // }) + // ), + FilterOperation( + filter: { GammaAdjustment() }, + listName: "Gamma", + titleName: "Gamma", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 3.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.gamma = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), -//// TODO : Tone curve + //// TODO : Tone curve FilterOperation( - filter:{HighlightsAndShadows()}, - listName:"Highlights and shadows", - titleName:"Highlights and Shadows", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { HighlightsAndShadows() }, + listName: "Highlights and shadows", + titleName: "Highlights and Shadows", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.highlights = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{Haze()}, - listName:"Haze / UV", - titleName:"Haze / UV", - sliderConfiguration:.enabled(minimumValue:-0.2, maximumValue:0.2, initialValue:0.2), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { Haze() }, + listName: "Haze / UV", + titleName: "Haze / UV", + sliderConfiguration: .enabled(minimumValue: -0.2, maximumValue: 0.2, initialValue: 0.2), + sliderUpdateCallback: { (filter, sliderValue) in filter.distance = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{SepiaToneFilter()}, - listName:"Sepia tone", - titleName:"Sepia Tone", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { SepiaToneFilter() }, + listName: "Sepia tone", + titleName: "Sepia Tone", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.intensity = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{AmatorkaFilter()}, - listName:"Amatorka (Lookup)", - titleName:"Amatorka (Lookup)", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { AmatorkaFilter() }, + listName: "Amatorka (Lookup)", + titleName: "Amatorka (Lookup)", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.intensity = sliderValue - }, - filterOperationType:.singleInput + }, + filterOperationType: .singleInput ), FilterOperation( - filter:{MissEtikateFilter()}, - listName:"Miss Etikate (Lookup)", - titleName:"Miss Etikate (Lookup)", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { MissEtikateFilter() }, + listName: "Miss Etikate (Lookup)", + titleName: "Miss Etikate (Lookup)", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.intensity = sliderValue - }, - filterOperationType:.singleInput + }, + filterOperationType: .singleInput ), FilterOperation( - filter:{SoftElegance()}, - listName:"Soft elegance (Lookup)", - titleName:"Soft Elegance (Lookup)", - sliderConfiguration:.disabled, + filter: { SoftElegance() }, + listName: "Soft elegance (Lookup)", + titleName: "Soft Elegance (Lookup)", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{ColorInversion()}, - listName:"Color invert", - titleName:"Color Invert", - sliderConfiguration:.disabled, + filter: { ColorInversion() }, + listName: "Color invert", + titleName: "Color Invert", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{Solarize()}, - listName:"Solarize", - titleName:"Solarize", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.5), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { Solarize() }, + listName: "Solarize", + titleName: "Solarize", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.5), + sliderUpdateCallback: { (filter, sliderValue) in filter.threshold = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{Vibrance()}, - listName:"Vibrance", - titleName:"Vibrance", - sliderConfiguration:.enabled(minimumValue:-1.2, maximumValue:1.2, initialValue:0.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { Vibrance() }, + listName: "Vibrance", + titleName: "Vibrance", + sliderConfiguration: .enabled(minimumValue: -1.2, maximumValue: 1.2, initialValue: 0.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.vibrance = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{HighlightAndShadowTint()}, - listName:"Highlight and shadow tint", - titleName:"Highlight / Shadow Tint", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { HighlightAndShadowTint() }, + listName: "Highlight and shadow tint", + titleName: "Highlight / Shadow Tint", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.shadowTintIntensity = sliderValue }, - filterOperationType:.singleInput - ), - FilterOperation ( - filter:{Luminance()}, - listName:"Luminance", - titleName:"Luminance", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.singleInput - ), -// FilterOperation( -// filter:{Histogram(type:.rgb)}, -// listName:"Histogram", -// titleName:"Histogram", -// sliderConfiguration:.enabled(minimumValue:4.0, maximumValue:32.0, initialValue:16.0), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.downsamplingFactor = UInt(round(sliderValue)) -// }, -// filterOperationType:.custom(filterSetupFunction: {(camera, filter, outputView) in -// let castFilter = filter as! Histogram -// let histogramGraph = HistogramDisplay() -// histogramGraph.overriddenOutputSize = Size(width:256.0, height:330.0) -// let blendFilter = AlphaBlend() -// blendFilter.mix = 0.75 -// camera --> blendFilter -// camera --> castFilter --> histogramGraph --> blendFilter --> outputView -// -// return blendFilter -// }) -// ), -// FilterOperation ( -// filter:{HistogramEqualization(type:.rgb)}, -// listName:"Histogram equalization", -// titleName:"Histogram Equalization", -// sliderConfiguration:.disabled, -// sliderUpdateCallback:nil, -// filterOperationType:.singleInput -// ), -// FilterOperation( -// filter:{AverageColorExtractor()}, -// listName:"Average color", -// titleName:"Average Color", -// sliderConfiguration:.disabled, -// sliderUpdateCallback: nil, -// filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in -// let castFilter = filter as! AverageColorExtractor -// let colorGenerator = SolidColorGenerator(size:outputView.sizeInPixels) -// -// castFilter.extractedColorCallback = {color in -// colorGenerator.renderColor(color) -// } -// camera --> castFilter -// colorGenerator --> outputView -// return colorGenerator -// }) -// ), -// FilterOperation( -// filter:{AverageLuminanceExtractor()}, -// listName:"Average luminosity", -// titleName:"Average Luminosity", -// sliderConfiguration:.disabled, -// sliderUpdateCallback: nil, -// filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in -// let castFilter = filter as! AverageLuminanceExtractor -// let colorGenerator = SolidColorGenerator(size:outputView.sizeInPixels) -// -// castFilter.extractedLuminanceCallback = {luminosity in -// colorGenerator.renderColor(Color(red:luminosity, green:luminosity, blue:luminosity)) -// } -// -// camera --> castFilter -// colorGenerator --> outputView -// return colorGenerator -// }) -// ), - FilterOperation( - filter:{LuminanceThreshold()}, - listName:"Luminance threshold", - titleName:"Luminance Threshold", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.5), - sliderUpdateCallback: {(filter, sliderValue) in + filterOperationType: .singleInput + ), + FilterOperation( + filter: { Luminance() }, + listName: "Luminance", + titleName: "Luminance", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .singleInput + ), + // FilterOperation( + // filter:{Histogram(type:.rgb)}, + // listName:"Histogram", + // titleName:"Histogram", + // sliderConfiguration:.enabled(minimumValue:4.0, maximumValue:32.0, initialValue:16.0), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.downsamplingFactor = UInt(round(sliderValue)) + // }, + // filterOperationType:.custom(filterSetupFunction: {(camera, filter, outputView) in + // let castFilter = filter as! Histogram + // let histogramGraph = HistogramDisplay() + // histogramGraph.overriddenOutputSize = Size(width:256.0, height:330.0) + // let blendFilter = AlphaBlend() + // blendFilter.mix = 0.75 + // camera --> blendFilter + // camera --> castFilter --> histogramGraph --> blendFilter --> outputView + // + // return blendFilter + // }) + // ), + // FilterOperation ( + // filter:{HistogramEqualization(type:.rgb)}, + // listName:"Histogram equalization", + // titleName:"Histogram Equalization", + // sliderConfiguration:.disabled, + // sliderUpdateCallback:nil, + // filterOperationType:.singleInput + // ), + // FilterOperation( + // filter:{AverageColorExtractor()}, + // listName:"Average color", + // titleName:"Average Color", + // sliderConfiguration:.disabled, + // sliderUpdateCallback: nil, + // filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + // let castFilter = filter as! AverageColorExtractor + // let colorGenerator = SolidColorGenerator(size:outputView.sizeInPixels) + // + // castFilter.extractedColorCallback = {color in + // colorGenerator.renderColor(color) + // } + // camera --> castFilter + // colorGenerator --> outputView + // return colorGenerator + // }) + // ), + // FilterOperation( + // filter:{AverageLuminanceExtractor()}, + // listName:"Average luminosity", + // titleName:"Average Luminosity", + // sliderConfiguration:.disabled, + // sliderUpdateCallback: nil, + // filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + // let castFilter = filter as! AverageLuminanceExtractor + // let colorGenerator = SolidColorGenerator(size:outputView.sizeInPixels) + // + // castFilter.extractedLuminanceCallback = {luminosity in + // colorGenerator.renderColor(Color(red:luminosity, green:luminosity, blue:luminosity)) + // } + // + // camera --> castFilter + // colorGenerator --> outputView + // return colorGenerator + // }) + // ), + FilterOperation( + filter: { LuminanceThreshold() }, + listName: "Luminance threshold", + titleName: "Luminance Threshold", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.5), + sliderUpdateCallback: { (filter, sliderValue) in filter.threshold = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{AdaptiveThreshold()}, - listName:"Adaptive threshold", - titleName:"Adaptive Threshold", - sliderConfiguration:.enabled(minimumValue:1.0, maximumValue:20.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { AdaptiveThreshold() }, + listName: "Adaptive threshold", + titleName: "Adaptive Threshold", + sliderConfiguration: .enabled(minimumValue: 1.0, maximumValue: 20.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.blurRadiusInPixels = sliderValue }, - filterOperationType:.singleInput - ), -// FilterOperation( -// filter:{AverageLuminanceThreshold()}, -// listName:"Average luminance threshold", -// titleName:"Avg. Lum. Threshold", -// sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:2.0, initialValue:1.0), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.thresholdMultiplier = sliderValue -// }, -// filterOperationType:.singleInput -// ), - FilterOperation( - filter:{Pixellate()}, - listName:"Pixellate", - titleName:"Pixellate", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:0.3, initialValue:0.05), - sliderUpdateCallback: {(filter, sliderValue) in + filterOperationType: .singleInput + ), + // FilterOperation( + // filter:{AverageLuminanceThreshold()}, + // listName:"Average luminance threshold", + // titleName:"Avg. Lum. Threshold", + // sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:2.0, initialValue:1.0), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.thresholdMultiplier = sliderValue + // }, + // filterOperationType:.singleInput + // ), + FilterOperation( + filter: { Pixellate() }, + listName: "Pixellate", + titleName: "Pixellate", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 0.3, initialValue: 0.05), + sliderUpdateCallback: { (filter, sliderValue) in filter.fractionalWidthOfAPixel = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{PolarPixellate()}, - listName:"Polar pixellate", - titleName:"Polar Pixellate", - sliderConfiguration:.enabled(minimumValue:-0.1, maximumValue:0.1, initialValue:0.05), - sliderUpdateCallback: {(filter, sliderValue) in - filter.pixelSize = Size(width:sliderValue, height:sliderValue) + filter: { PolarPixellate() }, + listName: "Polar pixellate", + titleName: "Polar Pixellate", + sliderConfiguration: .enabled(minimumValue: -0.1, maximumValue: 0.1, initialValue: 0.05), + sliderUpdateCallback: { (filter, sliderValue) in + filter.pixelSize = Size(width: sliderValue, height: sliderValue) }, - filterOperationType:.singleInput - ), -// FilterOperation( -// filter:{Pixellate()}, -// listName:"Masked Pixellate", -// titleName:"Masked Pixellate", -// sliderConfiguration:.disabled, -// sliderUpdateCallback: nil, -// filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in -// let castFilter = filter as! Pixellate -// castFilter.fractionalWidthOfAPixel = 0.05 -// // TODO: Find a way to not hardcode these values -//#if os(iOS) -// let circleGenerator = CircleGenerator(size:Size(width:480, height:640)) -//#else -// let circleGenerator = CircleGenerator(size:Size(width:1280, height:720)) -//#endif -// castFilter.mask = circleGenerator -// circleGenerator.renderCircleOfRadius(0.25, center:Position.center, circleColor:Color.white, backgroundColor:Color.transparent) -// camera --> castFilter --> outputView -// return nil -// }) -// ), - FilterOperation( - filter:{PolkaDot()}, - listName:"Polka dot", - titleName:"Polka Dot", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:0.3, initialValue:0.05), - sliderUpdateCallback: {(filter, sliderValue) in + filterOperationType: .singleInput + ), + // FilterOperation( + // filter:{Pixellate()}, + // listName:"Masked Pixellate", + // titleName:"Masked Pixellate", + // sliderConfiguration:.disabled, + // sliderUpdateCallback: nil, + // filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + // let castFilter = filter as! Pixellate + // castFilter.fractionalWidthOfAPixel = 0.05 + // // TODO: Find a way to not hardcode these values + //#if os(iOS) + // let circleGenerator = CircleGenerator(size:Size(width:480, height:640)) + //#else + // let circleGenerator = CircleGenerator(size:Size(width:1280, height:720)) + //#endif + // castFilter.mask = circleGenerator + // circleGenerator.renderCircleOfRadius(0.25, center:Position.center, circleColor:Color.white, backgroundColor:Color.transparent) + // camera --> castFilter --> outputView + // return nil + // }) + // ), + FilterOperation( + filter: { PolkaDot() }, + listName: "Polka dot", + titleName: "Polka Dot", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 0.3, initialValue: 0.05), + sliderUpdateCallback: { (filter, sliderValue) in filter.fractionalWidthOfAPixel = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{Halftone()}, - listName:"Halftone", - titleName:"Halftone", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:0.05, initialValue:0.01), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { Halftone() }, + listName: "Halftone", + titleName: "Halftone", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 0.05, initialValue: 0.01), + sliderUpdateCallback: { (filter, sliderValue) in filter.fractionalWidthOfAPixel = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{Crosshatch()}, - listName:"Crosshatch", - titleName:"Crosshatch", - sliderConfiguration:.enabled(minimumValue:0.01, maximumValue:0.06, initialValue:0.03), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { Crosshatch() }, + listName: "Crosshatch", + titleName: "Crosshatch", + sliderConfiguration: .enabled(minimumValue: 0.01, maximumValue: 0.06, initialValue: 0.03), + sliderUpdateCallback: { (filter, sliderValue) in filter.crossHatchSpacing = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{SobelEdgeDetection()}, - listName:"Sobel edge detection", - titleName:"Sobel Edge Detection", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.25), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { SobelEdgeDetection() }, + listName: "Sobel edge detection", + titleName: "Sobel Edge Detection", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.25), + sliderUpdateCallback: { (filter, sliderValue) in filter.edgeStrength = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{PrewittEdgeDetection()}, - listName:"Prewitt edge detection", - titleName:"Prewitt Edge Detection", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { PrewittEdgeDetection() }, + listName: "Prewitt edge detection", + titleName: "Prewitt Edge Detection", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.edgeStrength = sliderValue }, - filterOperationType:.singleInput - ), -// FilterOperation( -// filter:{CannyEdgeDetection()}, -// listName:"Canny edge detection", -// titleName:"Canny Edge Detection", -// sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:4.0, initialValue:1.0), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.blurRadiusInPixels = sliderValue -// }, -// filterOperationType:.singleInput -// ), - FilterOperation( - filter:{ThresholdSobelEdgeDetection()}, - listName:"Threshold edge detection", - titleName:"Threshold Edge Detection", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.25), - sliderUpdateCallback: {(filter, sliderValue) in + filterOperationType: .singleInput + ), + // FilterOperation( + // filter:{CannyEdgeDetection()}, + // listName:"Canny edge detection", + // titleName:"Canny Edge Detection", + // sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:4.0, initialValue:1.0), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.blurRadiusInPixels = sliderValue + // }, + // filterOperationType:.singleInput + // ), + FilterOperation( + filter: { ThresholdSobelEdgeDetection() }, + listName: "Threshold edge detection", + titleName: "Threshold Edge Detection", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.25), + sliderUpdateCallback: { (filter, sliderValue) in filter.threshold = sliderValue }, - filterOperationType:.singleInput - ), -// FilterOperation( -// filter:{HarrisCornerDetector()}, -// listName:"Harris corner detector", -// titleName:"Harris Corner Detector", -// sliderConfiguration:.enabled(minimumValue:0.01, maximumValue:0.70, initialValue:0.20), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.threshold = sliderValue -// }, -// filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in -// let castFilter = filter as! HarrisCornerDetector -// // TODO: Get this more dynamically sized -//#if os(iOS) -// let crosshairGenerator = CrosshairGenerator(size:Size(width:480, height:640)) -//#else -// let crosshairGenerator = CrosshairGenerator(size:Size(width:1280, height:720)) -//#endif -// crosshairGenerator.crosshairWidth = 15.0 -// -// castFilter.cornersDetectedCallback = { corners in -// crosshairGenerator.renderCrosshairs(corners) -// } -// -// camera --> castFilter -// -// let blendFilter = AlphaBlend() -// camera --> blendFilter --> outputView -// crosshairGenerator --> blendFilter -// -// return blendFilter -// }) -// ), -// FilterOperation( -// filter:{NobleCornerDetector()}, -// listName:"Noble corner detector", -// titleName:"Noble Corner Detector", -// sliderConfiguration:.enabled(minimumValue:0.01, maximumValue:0.70, initialValue:0.20), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.threshold = sliderValue -// }, -// filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in -// let castFilter = filter as! NobleCornerDetector -// // TODO: Get this more dynamically sized -//#if os(iOS) -// let crosshairGenerator = CrosshairGenerator(size:Size(width:480, height:640)) -//#else -// let crosshairGenerator = CrosshairGenerator(size:Size(width:1280, height:720)) -//#endif -// crosshairGenerator.crosshairWidth = 15.0 -// -// castFilter.cornersDetectedCallback = { corners in -// crosshairGenerator.renderCrosshairs(corners) -// } -// -// camera --> castFilter -// -// let blendFilter = AlphaBlend() -// camera --> blendFilter --> outputView -// crosshairGenerator --> blendFilter -// -// return blendFilter -// }) -// ), -// FilterOperation( -// filter:{ShiTomasiFeatureDetector()}, -// listName:"Shi-Tomasi feature detector", -// titleName:"Shi-Tomasi Feature Detector", -// sliderConfiguration:.enabled(minimumValue:0.01, maximumValue:0.70, initialValue:0.20), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.threshold = sliderValue -// }, -// filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in -// let castFilter = filter as! ShiTomasiFeatureDetector -// // TODO: Get this more dynamically sized -//#if os(iOS) -// let crosshairGenerator = CrosshairGenerator(size:Size(width:480, height:640)) -//#else -// let crosshairGenerator = CrosshairGenerator(size:Size(width:1280, height:720)) -//#endif -// crosshairGenerator.crosshairWidth = 15.0 -// -// castFilter.cornersDetectedCallback = { corners in -// crosshairGenerator.renderCrosshairs(corners) -// } -// -// camera --> castFilter -// -// let blendFilter = AlphaBlend() -// camera --> blendFilter --> outputView -// crosshairGenerator --> blendFilter -// -// return blendFilter -// }) -// ), -// // TODO: Hough transform line detector - FilterOperation( - filter:{ColourFASTFeatureDetection()}, - listName:"ColourFAST feature detection", - titleName:"ColourFAST Features", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.singleInput - ), - FilterOperation( - filter:{LowPassFilter()}, - listName:"Low pass", - titleName:"Low Pass", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.5), - sliderUpdateCallback: {(filter, sliderValue) in + filterOperationType: .singleInput + ), + // FilterOperation( + // filter:{HarrisCornerDetector()}, + // listName:"Harris corner detector", + // titleName:"Harris Corner Detector", + // sliderConfiguration:.enabled(minimumValue:0.01, maximumValue:0.70, initialValue:0.20), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.threshold = sliderValue + // }, + // filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + // let castFilter = filter as! HarrisCornerDetector + // // TODO: Get this more dynamically sized + //#if os(iOS) + // let crosshairGenerator = CrosshairGenerator(size:Size(width:480, height:640)) + //#else + // let crosshairGenerator = CrosshairGenerator(size:Size(width:1280, height:720)) + //#endif + // crosshairGenerator.crosshairWidth = 15.0 + // + // castFilter.cornersDetectedCallback = { corners in + // crosshairGenerator.renderCrosshairs(corners) + // } + // + // camera --> castFilter + // + // let blendFilter = AlphaBlend() + // camera --> blendFilter --> outputView + // crosshairGenerator --> blendFilter + // + // return blendFilter + // }) + // ), + // FilterOperation( + // filter:{NobleCornerDetector()}, + // listName:"Noble corner detector", + // titleName:"Noble Corner Detector", + // sliderConfiguration:.enabled(minimumValue:0.01, maximumValue:0.70, initialValue:0.20), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.threshold = sliderValue + // }, + // filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + // let castFilter = filter as! NobleCornerDetector + // // TODO: Get this more dynamically sized + //#if os(iOS) + // let crosshairGenerator = CrosshairGenerator(size:Size(width:480, height:640)) + //#else + // let crosshairGenerator = CrosshairGenerator(size:Size(width:1280, height:720)) + //#endif + // crosshairGenerator.crosshairWidth = 15.0 + // + // castFilter.cornersDetectedCallback = { corners in + // crosshairGenerator.renderCrosshairs(corners) + // } + // + // camera --> castFilter + // + // let blendFilter = AlphaBlend() + // camera --> blendFilter --> outputView + // crosshairGenerator --> blendFilter + // + // return blendFilter + // }) + // ), + // FilterOperation( + // filter:{ShiTomasiFeatureDetector()}, + // listName:"Shi-Tomasi feature detector", + // titleName:"Shi-Tomasi Feature Detector", + // sliderConfiguration:.enabled(minimumValue:0.01, maximumValue:0.70, initialValue:0.20), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.threshold = sliderValue + // }, + // filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + // let castFilter = filter as! ShiTomasiFeatureDetector + // // TODO: Get this more dynamically sized + //#if os(iOS) + // let crosshairGenerator = CrosshairGenerator(size:Size(width:480, height:640)) + //#else + // let crosshairGenerator = CrosshairGenerator(size:Size(width:1280, height:720)) + //#endif + // crosshairGenerator.crosshairWidth = 15.0 + // + // castFilter.cornersDetectedCallback = { corners in + // crosshairGenerator.renderCrosshairs(corners) + // } + // + // camera --> castFilter + // + // let blendFilter = AlphaBlend() + // camera --> blendFilter --> outputView + // crosshairGenerator --> blendFilter + // + // return blendFilter + // }) + // ), + // // TODO: Hough transform line detector + FilterOperation( + filter: { ColourFASTFeatureDetection() }, + listName: "ColourFAST feature detection", + titleName: "ColourFAST Features", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .singleInput + ), + FilterOperation( + filter: { LowPassFilter() }, + listName: "Low pass", + titleName: "Low Pass", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.5), + sliderUpdateCallback: { (filter, sliderValue) in filter.strength = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{HighPassFilter()}, - listName:"High pass", - titleName:"High Pass", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.5), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { HighPassFilter() }, + listName: "High pass", + titleName: "High Pass", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.5), + sliderUpdateCallback: { (filter, sliderValue) in filter.strength = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), -// // TODO: Motion detector -// + // // TODO: Motion detector + // FilterOperation( - filter:{SketchFilter()}, - listName:"Sketch", - titleName:"Sketch", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.5), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { SketchFilter() }, + listName: "Sketch", + titleName: "Sketch", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.5), + sliderUpdateCallback: { (filter, sliderValue) in filter.edgeStrength = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{ThresholdSketchFilter()}, - listName:"Threshold Sketch", - titleName:"Threshold Sketch", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.25), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { ThresholdSketchFilter() }, + listName: "Threshold Sketch", + titleName: "Threshold Sketch", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.25), + sliderUpdateCallback: { (filter, sliderValue) in filter.threshold = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{ToonFilter()}, - listName:"Toon", - titleName:"Toon", - sliderConfiguration:.disabled, + filter: { ToonFilter() }, + listName: "Toon", + titleName: "Toon", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{SmoothToonFilter()}, - listName:"Smooth toon", - titleName:"Smooth Toon", - sliderConfiguration:.enabled(minimumValue:1.0, maximumValue:6.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { SmoothToonFilter() }, + listName: "Smooth toon", + titleName: "Smooth Toon", + sliderConfiguration: .enabled(minimumValue: 1.0, maximumValue: 6.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.blurRadiusInPixels = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{TiltShift()}, - listName:"Tilt shift", - titleName:"Tilt Shift", - sliderConfiguration:.enabled(minimumValue:0.2, maximumValue:0.8, initialValue:0.5), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { TiltShift() }, + listName: "Tilt shift", + titleName: "Tilt Shift", + sliderConfiguration: .enabled(minimumValue: 0.2, maximumValue: 0.8, initialValue: 0.5), + sliderUpdateCallback: { (filter, sliderValue) in filter.topFocusLevel = sliderValue - 0.1 filter.bottomFocusLevel = sliderValue + 0.1 }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{CGAColorspaceFilter()}, - listName:"CGA colorspace", - titleName:"CGA Colorspace", - sliderConfiguration:.disabled, + filter: { CGAColorspaceFilter() }, + listName: "CGA colorspace", + titleName: "CGA Colorspace", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.singleInput - ), -// FilterOperation( -// filter:{() -> GPUImage.Posterize in -// return GPUImage.Posterize()}, -// listName:"Posterize", -// titleName:"Posterize", -// sliderConfiguration:.enabled(minimumValue:1.0, maximumValue:20.0, initialValue:10.0), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.colorLevels = round(Float(sliderValue)) -// }, -// filterOperationType:.singleInput -// ), - FilterOperation( - filter:{Convolution3x3()}, - listName:"3x3 convolution", - titleName:"3x3 convolution", - sliderConfiguration:.disabled, + filterOperationType: .singleInput + ), + // FilterOperation( + // filter:{() -> GPUImage.Posterize in + // return GPUImage.Posterize()}, + // listName:"Posterize", + // titleName:"Posterize", + // sliderConfiguration:.enabled(minimumValue:1.0, maximumValue:20.0, initialValue:10.0), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.colorLevels = round(Float(sliderValue)) + // }, + // filterOperationType:.singleInput + // ), + FilterOperation( + filter: { Convolution3x3() }, + listName: "3x3 convolution", + titleName: "3x3 convolution", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + filterOperationType: .custom(filterSetupFunction: { (camera, filter, outputView) in let castFilter = filter as! Convolution3x3 - castFilter.convolutionKernel = Matrix3x3(rowMajorValues:[ + castFilter.convolutionKernel = Matrix3x3(rowMajorValues: [ -1.0, 0.0, 1.0, -2.0, 0.0, 2.0, - -1.0, 0.0, 1.0]) - + -1.0, 0.0, 1.0, + ]) + camera --> castFilter --> outputView - + return nil }) ), FilterOperation( - filter:{EmbossFilter()}, - listName:"Emboss", - titleName:"Emboss", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:5.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { EmbossFilter() }, + listName: "Emboss", + titleName: "Emboss", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 5.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.intensity = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{Laplacian()}, - listName:"Laplacian", - titleName:"Laplacian", - sliderConfiguration:.disabled, + filter: { Laplacian() }, + listName: "Laplacian", + titleName: "Laplacian", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{ChromaKeying()}, - listName:"Chroma key", - titleName:"Chroma Key", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.00, initialValue:0.40), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { ChromaKeying() }, + listName: "Chroma key", + titleName: "Chroma Key", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.00, initialValue: 0.40), + sliderUpdateCallback: { (filter, sliderValue) in filter.thresholdSensitivity = sliderValue }, - filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + filterOperationType: .custom(filterSetupFunction: { (camera, filter, outputView) in let castFilter = filter as! ChromaKeying - + let blendFilter = AlphaBlend() blendFilter.mix = 1.0 - - let inputImage = PictureInput(imageName:blendImageName) - + + let inputImage = PictureInput(imageName: blendImageName) + inputImage --> blendFilter camera --> castFilter --> blendFilter --> outputView inputImage.processImage() return blendFilter }) ), -// FilterOperation( -// filter:{KuwaharaFilter()}, -// listName:"Kuwahara", -// titleName:"Kuwahara", -// sliderConfiguration:.enabled(minimumValue:3.0, maximumValue:9.0, initialValue:3.0), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.radius = Int(round(sliderValue)) -// }, -// filterOperationType:.singleInput -// ), - FilterOperation( - filter:{KuwaharaRadius3Filter()}, - listName:"Kuwahara (radius 3)", - titleName:"Kuwahara (Radius 3)", - sliderConfiguration:.disabled, + // FilterOperation( + // filter:{KuwaharaFilter()}, + // listName:"Kuwahara", + // titleName:"Kuwahara", + // sliderConfiguration:.enabled(minimumValue:3.0, maximumValue:9.0, initialValue:3.0), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.radius = Int(round(sliderValue)) + // }, + // filterOperationType:.singleInput + // ), + FilterOperation( + filter: { KuwaharaRadius3Filter() }, + listName: "Kuwahara (radius 3)", + titleName: "Kuwahara (Radius 3)", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{Vignette()}, - listName:"Vignette", - titleName:"Vignette", - sliderConfiguration:.enabled(minimumValue:0.5, maximumValue:0.9, initialValue:0.75), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { Vignette() }, + listName: "Vignette", + titleName: "Vignette", + sliderConfiguration: .enabled(minimumValue: 0.5, maximumValue: 0.9, initialValue: 0.75), + sliderUpdateCallback: { (filter, sliderValue) in filter.end = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{GaussianBlur()}, - listName:"Gaussian blur", - titleName:"Gaussian Blur", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:40.0, initialValue:2.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { GaussianBlur() }, + listName: "Gaussian blur", + titleName: "Gaussian Blur", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 40.0, initialValue: 2.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.blurRadiusInPixels = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{BoxBlur()}, - listName:"Box blur", - titleName:"Box Blur", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:40.0, initialValue:2.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { BoxBlur() }, + listName: "Box blur", + titleName: "Box Blur", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 40.0, initialValue: 2.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.blurRadiusInPixels = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{MedianFilter()}, - listName:"Median", - titleName:"Median", - sliderConfiguration:.disabled, + filter: { MedianFilter() }, + listName: "Median", + titleName: "Median", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.singleInput - ), -// FilterOperation( -// filter:{BilateralBlur()}, -// listName:"Bilateral blur", -// titleName:"Bilateral Blur", -// sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:10.0, initialValue:1.0), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.distanceNormalizationFactor = sliderValue -// }, -// filterOperationType:.singleInput -// ), -// FilterOperation( -// filter:{MotionBlur()}, -// listName:"Motion blur", -// titleName:"Motion Blur", -// sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:180.0, initialValue:0.0), -// sliderUpdateCallback: {(filter, sliderValue) in -// filter.blurAngle = sliderValue -// }, -// filterOperationType:.singleInput -// ), - FilterOperation( - filter:{ZoomBlur()}, - listName:"Zoom blur", - titleName:"Zoom Blur", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:2.5, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filterOperationType: .singleInput + ), + // FilterOperation( + // filter:{BilateralBlur()}, + // listName:"Bilateral blur", + // titleName:"Bilateral Blur", + // sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:10.0, initialValue:1.0), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.distanceNormalizationFactor = sliderValue + // }, + // filterOperationType:.singleInput + // ), + // FilterOperation( + // filter:{MotionBlur()}, + // listName:"Motion blur", + // titleName:"Motion Blur", + // sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:180.0, initialValue:0.0), + // sliderUpdateCallback: {(filter, sliderValue) in + // filter.blurAngle = sliderValue + // }, + // filterOperationType:.singleInput + // ), + FilterOperation( + filter: { ZoomBlur() }, + listName: "Zoom blur", + titleName: "Zoom Blur", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 2.5, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.blurSize = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), - FilterOperation( // TODO: Make this only partially applied to the view - filter:{iOSBlur()}, - listName:"iOS 7 blur", - titleName:"iOS 7 Blur", - sliderConfiguration:.disabled, + FilterOperation( // TODO: Make this only partially applied to the view + filter: { iOSBlur() }, + listName: "iOS 7 blur", + titleName: "iOS 7 Blur", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{SwirlDistortion()}, - listName:"Swirl", - titleName:"Swirl", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:2.0, initialValue:1.0), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { SwirlDistortion() }, + listName: "Swirl", + titleName: "Swirl", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 2.0, initialValue: 1.0), + sliderUpdateCallback: { (filter, sliderValue) in filter.angle = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{BulgeDistortion()}, - listName:"Bulge", - titleName:"Bulge", - sliderConfiguration:.enabled(minimumValue:-1.0, maximumValue:1.0, initialValue:0.5), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { BulgeDistortion() }, + listName: "Bulge", + titleName: "Bulge", + sliderConfiguration: .enabled(minimumValue: -1.0, maximumValue: 1.0, initialValue: 0.5), + sliderUpdateCallback: { (filter, sliderValue) in // filter.scale = sliderValue filter.center = Position(0.5, sliderValue) }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{PinchDistortion()}, - listName:"Pinch", - titleName:"Pinch", - sliderConfiguration:.enabled(minimumValue:-2.0, maximumValue:2.0, initialValue:0.5), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { PinchDistortion() }, + listName: "Pinch", + titleName: "Pinch", + sliderConfiguration: .enabled(minimumValue: -2.0, maximumValue: 2.0, initialValue: 0.5), + sliderUpdateCallback: { (filter, sliderValue) in filter.scale = sliderValue }, - filterOperationType:.singleInput + filterOperationType: .singleInput ), FilterOperation( - filter:{SphereRefraction()}, - listName:"Sphere refraction", - titleName:"Sphere Refraction", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.15), - sliderUpdateCallback:{(filter, sliderValue) in + filter: { SphereRefraction() }, + listName: "Sphere refraction", + titleName: "Sphere Refraction", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.15), + sliderUpdateCallback: { (filter, sliderValue) in filter.radius = sliderValue }, - filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + filterOperationType: .custom(filterSetupFunction: { (camera, filter, outputView) in let castFilter = filter as! SphereRefraction - + // Provide a blurred image for a cool-looking background let gaussianBlur = GaussianBlur() gaussianBlur.blurRadiusInPixels = 5.0 - + let blendFilter = AlphaBlend() blendFilter.mix = 1.0 - + camera --> gaussianBlur --> blendFilter --> outputView camera --> castFilter --> blendFilter - + return blendFilter }) ), FilterOperation( - filter:{GlassSphereRefraction()}, - listName:"Glass sphere", - titleName:"Glass Sphere", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.15), - sliderUpdateCallback:{(filter, sliderValue) in + filter: { GlassSphereRefraction() }, + listName: "Glass sphere", + titleName: "Glass Sphere", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.15), + sliderUpdateCallback: { (filter, sliderValue) in filter.radius = sliderValue }, - filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in + filterOperationType: .custom(filterSetupFunction: { (camera, filter, outputView) in let castFilter = filter as! GlassSphereRefraction - + // Provide a blurred image for a cool-looking background let gaussianBlur = GaussianBlur() gaussianBlur.blurRadiusInPixels = 5.0 - + let blendFilter = AlphaBlend() blendFilter.mix = 1.0 - + camera --> gaussianBlur --> blendFilter --> outputView camera --> castFilter --> blendFilter - + return blendFilter }) ), - FilterOperation ( - filter:{StretchDistortion()}, - listName:"Stretch", - titleName:"Stretch", - sliderConfiguration:.disabled, + FilterOperation( + filter: { StretchDistortion() }, + listName: "Stretch", + titleName: "Stretch", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.singleInput - ), -// FilterOperation( -// filter:{Dilation()}, -// listName:"Dilation", -// titleName:"Dilation", -// sliderConfiguration:.disabled, -// sliderUpdateCallback: nil, -// filterOperationType:.singleInput -// ), -// FilterOperation( -// filter:{Erosion()}, -// listName:"Erosion", -// titleName:"Erosion", -// sliderConfiguration:.disabled, -// sliderUpdateCallback: nil, -// filterOperationType:.singleInput -// ), -// FilterOperation( -// filter:{OpeningFilter()}, -// listName:"Opening", -// titleName:"Opening", -// sliderConfiguration:.disabled, -// sliderUpdateCallback: nil, -// filterOperationType:.singleInput -// ), -// FilterOperation( -// filter:{ClosingFilter()}, -// listName:"Closing", -// titleName:"Closing", -// sliderConfiguration:.disabled, -// sliderUpdateCallback: nil, -// filterOperationType:.singleInput -// ), -// // TODO: Perlin noise -// // TODO: JFAVoronoi -// // TODO: Mosaic - FilterOperation( - filter:{LocalBinaryPattern()}, - listName:"Local binary pattern", - titleName:"Local Binary Pattern", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.singleInput - ), - FilterOperation( - filter:{ColorLocalBinaryPattern()}, - listName:"Local binary pattern (color)", - titleName:"Local Binary Pattern (Color)", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.singleInput - ), - FilterOperation( - filter:{DissolveBlend()}, - listName:"Dissolve blend", - titleName:"Dissolve Blend", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.5), - sliderUpdateCallback: {(filter, sliderValue) in + filterOperationType: .singleInput + ), + // FilterOperation( + // filter:{Dilation()}, + // listName:"Dilation", + // titleName:"Dilation", + // sliderConfiguration:.disabled, + // sliderUpdateCallback: nil, + // filterOperationType:.singleInput + // ), + // FilterOperation( + // filter:{Erosion()}, + // listName:"Erosion", + // titleName:"Erosion", + // sliderConfiguration:.disabled, + // sliderUpdateCallback: nil, + // filterOperationType:.singleInput + // ), + // FilterOperation( + // filter:{OpeningFilter()}, + // listName:"Opening", + // titleName:"Opening", + // sliderConfiguration:.disabled, + // sliderUpdateCallback: nil, + // filterOperationType:.singleInput + // ), + // FilterOperation( + // filter:{ClosingFilter()}, + // listName:"Closing", + // titleName:"Closing", + // sliderConfiguration:.disabled, + // sliderUpdateCallback: nil, + // filterOperationType:.singleInput + // ), + // // TODO: Perlin noise + // // TODO: JFAVoronoi + // // TODO: Mosaic + FilterOperation( + filter: { LocalBinaryPattern() }, + listName: "Local binary pattern", + titleName: "Local Binary Pattern", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .singleInput + ), + FilterOperation( + filter: { ColorLocalBinaryPattern() }, + listName: "Local binary pattern (color)", + titleName: "Local Binary Pattern (Color)", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .singleInput + ), + FilterOperation( + filter: { DissolveBlend() }, + listName: "Dissolve blend", + titleName: "Dissolve Blend", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.5), + sliderUpdateCallback: { (filter, sliderValue) in filter.mix = sliderValue }, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{ChromaKeyBlend()}, - listName:"Chroma key blend (green)", - titleName:"Chroma Key (Green)", - sliderConfiguration:.enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.4), - sliderUpdateCallback: {(filter, sliderValue) in + filter: { ChromaKeyBlend() }, + listName: "Chroma key blend (green)", + titleName: "Chroma Key (Green)", + sliderConfiguration: .enabled(minimumValue: 0.0, maximumValue: 1.0, initialValue: 0.4), + sliderUpdateCallback: { (filter, sliderValue) in filter.thresholdSensitivity = sliderValue }, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{AddBlend()}, - listName:"Add blend", - titleName:"Add Blend", - sliderConfiguration:.disabled, + filter: { AddBlend() }, + listName: "Add blend", + titleName: "Add Blend", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{DivideBlend()}, - listName:"Divide blend", - titleName:"Divide Blend", - sliderConfiguration:.disabled, + filter: { DivideBlend() }, + listName: "Divide blend", + titleName: "Divide Blend", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{MultiplyBlend()}, - listName:"Multiply blend", - titleName:"Multiply Blend", - sliderConfiguration:.disabled, + filter: { MultiplyBlend() }, + listName: "Multiply blend", + titleName: "Multiply Blend", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{OverlayBlend()}, - listName:"Overlay blend", - titleName:"Overlay Blend", - sliderConfiguration:.disabled, + filter: { OverlayBlend() }, + listName: "Overlay blend", + titleName: "Overlay Blend", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{LightenBlend()}, - listName:"Lighten blend", - titleName:"Lighten Blend", - sliderConfiguration:.disabled, + filter: { LightenBlend() }, + listName: "Lighten blend", + titleName: "Lighten Blend", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{DarkenBlend()}, - listName:"Darken blend", - titleName:"Darken Blend", - sliderConfiguration:.disabled, + filter: { DarkenBlend() }, + listName: "Darken blend", + titleName: "Darken Blend", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{ColorBurnBlend()}, - listName:"Color burn blend", - titleName:"Color Burn Blend", - sliderConfiguration:.disabled, + filter: { ColorBurnBlend() }, + listName: "Color burn blend", + titleName: "Color Burn Blend", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{ColorDodgeBlend()}, - listName:"Color dodge blend", - titleName:"Color Dodge Blend", - sliderConfiguration:.disabled, + filter: { ColorDodgeBlend() }, + listName: "Color dodge blend", + titleName: "Color Dodge Blend", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{LinearBurnBlend()}, - listName:"Linear burn blend", - titleName:"Linear Burn Blend", - sliderConfiguration:.disabled, + filter: { LinearBurnBlend() }, + listName: "Linear burn blend", + titleName: "Linear Burn Blend", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.blend + filterOperationType: .blend ), FilterOperation( - filter:{ScreenBlend()}, - listName:"Screen blend", - titleName:"Screen Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { ScreenBlend() }, + listName: "Screen blend", + titleName: "Screen Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), FilterOperation( - filter:{DifferenceBlend()}, - listName:"Difference blend", - titleName:"Difference Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { DifferenceBlend() }, + listName: "Difference blend", + titleName: "Difference Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), FilterOperation( - filter:{SubtractBlend()}, - listName:"Subtract blend", - titleName:"Subtract Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { SubtractBlend() }, + listName: "Subtract blend", + titleName: "Subtract Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), FilterOperation( - filter:{ExclusionBlend()}, - listName:"Exclusion blend", - titleName:"Exclusion Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { ExclusionBlend() }, + listName: "Exclusion blend", + titleName: "Exclusion Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), FilterOperation( - filter:{HardLightBlend()}, - listName:"Hard light blend", - titleName:"Hard Light Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { HardLightBlend() }, + listName: "Hard light blend", + titleName: "Hard Light Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), FilterOperation( - filter:{SoftLightBlend()}, - listName:"Soft light blend", - titleName:"Soft Light Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { SoftLightBlend() }, + listName: "Soft light blend", + titleName: "Soft Light Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), FilterOperation( - filter:{ColorBlend()}, - listName:"Color blend", - titleName:"Color Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { ColorBlend() }, + listName: "Color blend", + titleName: "Color Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), FilterOperation( - filter:{HueBlend()}, - listName:"Hue blend", - titleName:"Hue Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { HueBlend() }, + listName: "Hue blend", + titleName: "Hue Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), FilterOperation( - filter:{SaturationBlend()}, - listName:"Saturation blend", - titleName:"Saturation Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { SaturationBlend() }, + listName: "Saturation blend", + titleName: "Saturation Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), FilterOperation( - filter:{LuminosityBlend()}, - listName:"Luminosity blend", - titleName:"Luminosity Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { LuminosityBlend() }, + listName: "Luminosity blend", + titleName: "Luminosity Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), FilterOperation( - filter:{NormalBlend()}, - listName:"Normal blend", - titleName:"Normal Blend", - sliderConfiguration:.disabled, - sliderUpdateCallback:nil, - filterOperationType:.blend + filter: { NormalBlend() }, + listName: "Normal blend", + titleName: "Normal Blend", + sliderConfiguration: .disabled, + sliderUpdateCallback: nil, + filterOperationType: .blend ), - + FilterOperation( - filter:{GammaAdjustment()}, - listName:"Solid color", - titleName:"Solid color", - sliderConfiguration:.disabled, + filter: { GammaAdjustment() }, + listName: "Solid color", + titleName: "Solid color", + sliderConfiguration: .disabled, sliderUpdateCallback: nil, - filterOperationType:.custom(filterSetupFunction:{(camera, filter, outputView) in - let solidColorGenerator = SolidColorGenerator(size:Size(width: 400, height: 400)) + filterOperationType: .custom(filterSetupFunction: { (camera, filter, outputView) in + let solidColorGenerator = SolidColorGenerator(size: Size(width: 400, height: 400)) solidColorGenerator --> outputView solidColorGenerator.renderColor(Color.red) -// solidColorGenerator --> (filter as! GammaAdjustment) --> outputView + // solidColorGenerator --> (filter as! GammaAdjustment) --> outputView return nil }) ), diff --git a/examples/Mac/FilterShowcase/FilterShowcase/FilterShowcaseWindowController.swift b/examples/Mac/FilterShowcase/FilterShowcase/FilterShowcaseWindowController.swift index 09a7ccc9..e298640d 100755 --- a/examples/Mac/FilterShowcase/FilterShowcase/FilterShowcaseWindowController.swift +++ b/examples/Mac/FilterShowcase/FilterShowcase/FilterShowcaseWindowController.swift @@ -1,6 +1,6 @@ +import AVFoundation import Cocoa import GPUImage -import AVFoundation let blendImageName = "Lambeau.jpg" @@ -9,20 +9,20 @@ class FilterShowcaseWindowController: NSWindowController { @IBOutlet var filterView: RenderView! @IBOutlet weak var filterSlider: NSSlider! - - @objc dynamic var currentSliderValue:Float = 0.5 { + + @objc dynamic var currentSliderValue: Float = 0.5 { willSet(newSliderValue) { - switch (currentFilterOperation!.sliderConfiguration) { - case .enabled: currentFilterOperation!.updateBasedOnSliderValue(newSliderValue) - case .disabled: break + switch currentFilterOperation!.sliderConfiguration { + case .enabled: currentFilterOperation!.updateBasedOnSliderValue(newSliderValue) + case .disabled: break } } } - + var currentFilterOperation: FilterOperationInterface? - var videoCamera:Camera! - lazy var blendImage:PictureInput = { - return PictureInput(imageName:blendImageName) + var videoCamera: Camera! + lazy var blendImage: PictureInput = { + return PictureInput(imageName: blendImageName) }() var currentlySelectedRow = 1 @@ -30,7 +30,7 @@ class FilterShowcaseWindowController: NSWindowController { super.windowDidLoad() do { - videoCamera = try Camera(sessionPreset:.hd1280x720, location:.frontFacing) + videoCamera = try Camera(sessionPreset: .hd1280x720, location: .frontFacing) videoCamera.runBenchmark = true videoCamera.startCapture() } catch { @@ -38,58 +38,62 @@ class FilterShowcaseWindowController: NSWindowController { } self.changeSelectedRow(0) } - - func changeSelectedRow(_ row:Int) { - guard (currentlySelectedRow != row) else { return } + + func changeSelectedRow(_ row: Int) { + guard currentlySelectedRow != row else { return } currentlySelectedRow = row - + // Clean up everything from the previous filter selection first -// videoCamera.stopCapture() + // videoCamera.stopCapture() videoCamera.removeAllTargets() currentFilterOperation?.filter.removeAllTargets() currentFilterOperation?.secondInput?.removeAllTargets() - + currentFilterOperation = filterOperations[row] switch currentFilterOperation!.filterOperationType { - case .singleInput: - videoCamera.addTarget((currentFilterOperation!.filter)) - currentFilterOperation!.filter.addTarget(filterView!) - case .blend: - blendImage.removeAllTargets() - videoCamera.addTarget((currentFilterOperation!.filter)) - self.blendImage.addTarget((currentFilterOperation!.filter)) - currentFilterOperation!.filter.addTarget(filterView!) - self.blendImage.processImage() - case let .custom(filterSetupFunction:setupFunction): - currentFilterOperation!.configureCustomFilter(setupFunction(videoCamera!, currentFilterOperation!.filter, filterView!)) + case .singleInput: + videoCamera.addTarget((currentFilterOperation!.filter)) + currentFilterOperation!.filter.addTarget(filterView!) + case .blend: + blendImage.removeAllTargets() + videoCamera.addTarget((currentFilterOperation!.filter)) + self.blendImage.addTarget((currentFilterOperation!.filter)) + currentFilterOperation!.filter.addTarget(filterView!) + self.blendImage.processImage() + case let .custom(filterSetupFunction: setupFunction): + currentFilterOperation!.configureCustomFilter( + setupFunction(videoCamera!, currentFilterOperation!.filter, filterView!)) } - + switch currentFilterOperation!.sliderConfiguration { - case .disabled: - filterSlider.isEnabled = false - // case let .Enabled(minimumValue, initialValue, maximumValue, filterSliderCallback): - case let .enabled(minimumValue, maximumValue, initialValue): - filterSlider.minValue = Double(minimumValue) - filterSlider.maxValue = Double(maximumValue) - filterSlider.isEnabled = true - currentSliderValue = initialValue + case .disabled: + filterSlider.isEnabled = false + // case let .Enabled(minimumValue, initialValue, maximumValue, filterSliderCallback): + case let .enabled(minimumValue, maximumValue, initialValue): + filterSlider.minValue = Double(minimumValue) + filterSlider.maxValue = Double(maximumValue) + filterSlider.isEnabled = true + currentSliderValue = initialValue } - + videoCamera.startCapture() } -// MARK: - -// MARK: Table view delegate and datasource methods - - @objc func numberOfRowsInTableView(_ aTableView:NSTableView!) -> Int { + // MARK: - + // MARK: Table view delegate and datasource methods + + @objc func numberOfRowsInTableView(_ aTableView: NSTableView!) -> Int { return filterOperations.count } - - @objc func tableView(_ aTableView:NSTableView!, objectValueForTableColumn aTableColumn:NSTableColumn!, row rowIndex:Int) -> AnyObject! { - let filterInList:FilterOperationInterface = filterOperations[rowIndex] + + @objc func tableView( + _ aTableView: NSTableView!, objectValueForTableColumn aTableColumn: NSTableColumn!, + row rowIndex: Int + ) -> AnyObject! { + let filterInList: FilterOperationInterface = filterOperations[rowIndex] return filterInList.listName as NSString } - + @objc func tableViewSelectionDidChange(_ aNotification: Notification!) { if let currentTableView = aNotification.object as? NSTableView { let rowIndex = currentTableView.selectedRow diff --git a/examples/Mac/SimpleImageFilter/SimpleImageFilter/AppDelegate.swift b/examples/Mac/SimpleImageFilter/SimpleImageFilter/AppDelegate.swift index 215d4cb7..92605a2a 100755 --- a/examples/Mac/SimpleImageFilter/SimpleImageFilter/AppDelegate.swift +++ b/examples/Mac/SimpleImageFilter/SimpleImageFilter/AppDelegate.swift @@ -7,8 +7,8 @@ class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow! @IBOutlet weak var renderView: RenderView! - var image:PictureInput! - var filter:SaturationAdjustment! + var image: PictureInput! + var filter: SaturationAdjustment! @objc dynamic var filterValue = 1.0 { didSet { @@ -16,34 +16,33 @@ class AppDelegate: NSObject, NSApplicationDelegate { image.processImage() } } - + func applicationDidFinishLaunching(_ aNotification: Notification) { // Filtering image for saving - let testImage = NSImage(named:NSImage.Name(rawValue: "WID-small.jpg"))! -// let toonFilter = ToonFilter() + let testImage = NSImage(named: NSImage.Name(rawValue: "WID-small.jpg"))! + // let toonFilter = ToonFilter() let toonFilter = SaturationAdjustment() - let inputImageForSaving = PictureInput(image:testImage) + let inputImageForSaving = PictureInput(image: testImage) let pictureOutput = PictureOutput() pictureOutput.encodedImageAvailableCallback = { imageData in do { - let fileURL = URL(fileURLWithPath:"test.png") - try imageData.write(to:fileURL, options:.atomic) + let fileURL = URL(fileURLWithPath: "test.png") + try imageData.write(to: fileURL, options: .atomic) } catch { print("Couldn't write to file with error: \(error)") } } - + inputImageForSaving --> toonFilter --> pictureOutput - inputImageForSaving.processImage(synchronously:true) + inputImageForSaving.processImage(synchronously: true) // Filtering image for display - let inputImage = NSImage(named:NSImage.Name(rawValue: "Lambeau.jpg"))! - image = PictureInput(image:inputImage) - + let inputImage = NSImage(named: NSImage.Name(rawValue: "Lambeau.jpg"))! + image = PictureInput(image: inputImage) + filter = SaturationAdjustment() image --> filter --> renderView image.processImage() } } - diff --git a/examples/Mac/SimpleMovieFilter/SimpleMovieFilter/AppDelegate.swift b/examples/Mac/SimpleMovieFilter/SimpleMovieFilter/AppDelegate.swift index 106848fd..121dac03 100644 --- a/examples/Mac/SimpleMovieFilter/SimpleMovieFilter/AppDelegate.swift +++ b/examples/Mac/SimpleMovieFilter/SimpleMovieFilter/AppDelegate.swift @@ -6,22 +6,22 @@ class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow! @IBOutlet weak var renderView: RenderView! - - var movie:MovieInput! - var filter:Pixellate! - + + var movie: MovieInput! + var filter: Pixellate! + @objc dynamic var filterValue = 0.05 { didSet { filter.fractionalWidthOfAPixel = GLfloat(filterValue) } } - + func applicationDidFinishLaunching(_ aNotification: Notification) { let bundleURL = Bundle.main.resourceURL! - let movieURL = URL(string:"sample_iPod.m4v", relativeTo:bundleURL)! + let movieURL = URL(string: "sample_iPod.m4v", relativeTo: bundleURL)! do { - movie = try MovieInput(url:movieURL, playAtActualSpeed:true) + movie = try MovieInput(url: movieURL, playAtActualSpeed: true) filter = Pixellate() movie --> filter --> renderView movie.runBenchmark = true @@ -31,4 +31,3 @@ class AppDelegate: NSObject, NSApplicationDelegate { } } } - diff --git a/examples/Mac/SimpleVideoFilter/SimpleVideoFilter/AppDelegate.swift b/examples/Mac/SimpleVideoFilter/SimpleVideoFilter/AppDelegate.swift index 4f07120c..c66ecead 100755 --- a/examples/Mac/SimpleVideoFilter/SimpleVideoFilter/AppDelegate.swift +++ b/examples/Mac/SimpleVideoFilter/SimpleVideoFilter/AppDelegate.swift @@ -1,34 +1,34 @@ +import AVFoundation import Cocoa import GPUImage -import AVFoundation @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow! @IBOutlet weak var renderView: RenderView! - - var camera:Camera! - var filter:Pixellate! - @objc dynamic var filterSetting:Float = 0.01 { + var camera: Camera! + var filter: Pixellate! + + @objc dynamic var filterSetting: Float = 0.01 { didSet { filter.fractionalWidthOfAPixel = filterSetting } } - + @IBAction func capture(_ sender: AnyObject) { let imageSavingDialog = NSSavePanel() imageSavingDialog.allowedFileTypes = ["png"] let okayButton = imageSavingDialog.runModal() - + if okayButton == NSApplication.ModalResponse.OK { - filter.saveNextFrameToURL(imageSavingDialog.url!, format:.png) + filter.saveNextFrameToURL(imageSavingDialog.url!, format: .png) } } - + func applicationDidFinishLaunching(_ aNotification: Notification) { do { - camera = try Camera(sessionPreset:.vga640x480) + camera = try Camera(sessionPreset: .vga640x480) filter = Pixellate() camera --> filter --> renderView diff --git a/examples/Mac/SimpleVideoRecorder/SimpleVideoRecorder/AppDelegate.swift b/examples/Mac/SimpleVideoRecorder/SimpleVideoRecorder/AppDelegate.swift index e7de0f6d..43ad42e7 100644 --- a/examples/Mac/SimpleVideoRecorder/SimpleVideoRecorder/AppDelegate.swift +++ b/examples/Mac/SimpleVideoRecorder/SimpleVideoRecorder/AppDelegate.swift @@ -1,23 +1,23 @@ +import AVFoundation import Cocoa import GPUImage -import AVFoundation @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - @IBOutlet weak var window:NSWindow! - @IBOutlet var renderView:RenderView! + @IBOutlet weak var window: NSWindow! + @IBOutlet var renderView: RenderView! - var camera:Camera! - var filter:SmoothToonFilter! - var movieOutput:MovieOutput? + var camera: Camera! + var filter: SmoothToonFilter! + var movieOutput: MovieOutput? var isRecording = false func applicationDidFinishLaunching(_ aNotification: Notification) { do { - camera = try Camera(sessionPreset:.vga640x480) + camera = try Camera(sessionPreset: .vga640x480) filter = SmoothToonFilter() - + camera --> filter --> renderView camera.runBenchmark = false camera.startCapture() @@ -29,19 +29,21 @@ class AppDelegate: NSObject, NSApplicationDelegate { func applicationWillTerminate(_ aNotification: Notification) { camera.stopCapture() } - + @IBAction func record(_ sender: AnyObject) { - if (!isRecording) { + if !isRecording { let movieSavingDialog = NSSavePanel() movieSavingDialog.allowedFileTypes = ["mp4"] let okayButton = movieSavingDialog.runModal() - + if okayButton == NSApplication.ModalResponse.OK { do { self.isRecording = true -// movieOutput = try MovieOutput(URL:movieSavingDialog.url!, size:Size(width:1280, height:720), liveVideo:true) - movieOutput = try MovieOutput(URL:movieSavingDialog.url!, size:Size(width:640, height:480), liveVideo:true) -// camera.audioEncodingTarget = movieOutput + // movieOutput = try MovieOutput(URL:movieSavingDialog.url!, size:Size(width:1280, height:720), liveVideo:true) + movieOutput = try MovieOutput( + URL: movieSavingDialog.url!, size: Size(width: 640, height: 480), + liveVideo: true) + // camera.audioEncodingTarget = movieOutput filter --> movieOutput! movieOutput!.startRecording() (sender as! NSButton).title = "Stop" @@ -50,16 +52,15 @@ class AppDelegate: NSObject, NSApplicationDelegate { } } } else { - movieOutput?.finishRecording{ + movieOutput?.finishRecording { self.isRecording = false DispatchQueue.main.async { (sender as! NSButton).title = "Record" } -// self.camera.audioEncodingTarget = nil + // self.camera.audioEncodingTarget = nil self.movieOutput = nil } } } } - diff --git a/examples/iOS/FilterShowcase/FilterShowcaseSwift/AppDelegate.swift b/examples/iOS/FilterShowcase/FilterShowcaseSwift/AppDelegate.swift index b0eaff90..8bcf44eb 100644 --- a/examples/iOS/FilterShowcase/FilterShowcaseSwift/AppDelegate.swift +++ b/examples/iOS/FilterShowcase/FilterShowcaseSwift/AppDelegate.swift @@ -2,11 +2,13 @@ import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - + var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey:Any]?) -> Bool { + func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? + ) -> Bool { return true } } - diff --git a/examples/iOS/FilterShowcase/FilterShowcaseSwift/FilterDisplayViewController.swift b/examples/iOS/FilterShowcase/FilterShowcaseSwift/FilterDisplayViewController.swift index 05fceeb8..0bece0cc 100644 --- a/examples/iOS/FilterShowcase/FilterShowcaseSwift/FilterDisplayViewController.swift +++ b/examples/iOS/FilterShowcase/FilterShowcaseSwift/FilterDisplayViewController.swift @@ -1,6 +1,6 @@ -import UIKit -import GPUImage import AVFoundation +import GPUImage +import UIKit let blendImageName = "WID-small.jpg" @@ -8,14 +8,13 @@ class FilterDisplayViewController: UIViewController, UISplitViewControllerDelega @IBOutlet var filterSlider: UISlider? @IBOutlet var filterView: RenderView? - - let videoCamera:Camera? - var blendImage:PictureInput? - required init(coder aDecoder: NSCoder) - { + let videoCamera: Camera? + var blendImage: PictureInput? + + required init(coder aDecoder: NSCoder) { do { - videoCamera = try Camera(sessionPreset:.vga640x480, location:.backFacing) + videoCamera = try Camera(sessionPreset: .vga640x480, location: .backFacing) videoCamera!.runBenchmark = true } catch { videoCamera = nil @@ -24,19 +23,23 @@ class FilterDisplayViewController: UIViewController, UISplitViewControllerDelega super.init(coder: aDecoder)! } - + var filterOperation: FilterOperationInterface? - + func configureView() { guard let videoCamera = videoCamera else { - let errorAlertController = UIAlertController(title: NSLocalizedString("Error", comment: "Error"), message: "Couldn't initialize camera", preferredStyle: .alert) - errorAlertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK"), style: .default, handler: nil)) + let errorAlertController = UIAlertController( + title: NSLocalizedString("Error", comment: "Error"), + message: "Couldn't initialize camera", preferredStyle: .alert) + errorAlertController.addAction( + UIAlertAction( + title: NSLocalizedString("OK", comment: "OK"), style: .default, handler: nil)) self.present(errorAlertController, animated: true, completion: nil) return } if let currentFilterConfiguration = self.filterOperation { self.title = currentFilterConfiguration.titleName - + // Configure the filter chain, ending with the view if let view = self.filterView { switch currentFilterConfiguration.filterOperationType { @@ -45,14 +48,15 @@ class FilterDisplayViewController: UIViewController, UISplitViewControllerDelega currentFilterConfiguration.filter.addTarget(view) case .blend: videoCamera.addTarget(currentFilterConfiguration.filter) - self.blendImage = PictureInput(imageName:blendImageName) + self.blendImage = PictureInput(imageName: blendImageName) self.blendImage?.addTarget(currentFilterConfiguration.filter) self.blendImage?.processImage() currentFilterConfiguration.filter.addTarget(view) - case let .custom(filterSetupFunction:setupFunction): - currentFilterConfiguration.configureCustomFilter(setupFunction(videoCamera, currentFilterConfiguration.filter, view)) + case let .custom(filterSetupFunction: setupFunction): + currentFilterConfiguration.configureCustomFilter( + setupFunction(videoCamera, currentFilterConfiguration.filter, view)) } - + videoCamera.startCapture() } @@ -61,7 +65,7 @@ class FilterDisplayViewController: UIViewController, UISplitViewControllerDelega switch currentFilterConfiguration.sliderConfiguration { case .disabled: slider.isHidden = true -// case let .Enabled(minimumValue, initialValue, maximumValue, filterSliderCallback): + // case let .Enabled(minimumValue, initialValue, maximumValue, filterSliderCallback): case let .enabled(minimumValue, maximumValue, initialValue): slider.minimumValue = minimumValue slider.maximumValue = maximumValue @@ -70,15 +74,16 @@ class FilterDisplayViewController: UIViewController, UISplitViewControllerDelega self.updateSliderValue() } } - + } } - + @IBAction func updateSliderValue() { if let currentFilterConfiguration = self.filterOperation { - switch (currentFilterConfiguration.sliderConfiguration) { - case .enabled(_, _, _): currentFilterConfiguration.updateBasedOnSliderValue(Float(self.filterSlider!.value)) - case .disabled: break + switch currentFilterConfiguration.sliderConfiguration { + case .enabled(_, _, _): + currentFilterConfiguration.updateBasedOnSliderValue(Float(self.filterSlider!.value)) + case .disabled: break } } } @@ -94,14 +99,13 @@ class FilterDisplayViewController: UIViewController, UISplitViewControllerDelega videoCamera.removeAllTargets() blendImage?.removeAllTargets() } - + super.viewWillDisappear(animated) } - + override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } - diff --git a/examples/iOS/FilterShowcase/FilterShowcaseSwift/FilterListViewController.swift b/examples/iOS/FilterShowcase/FilterShowcaseSwift/FilterListViewController.swift index 430af00b..399a4024 100644 --- a/examples/iOS/FilterShowcase/FilterShowcaseSwift/FilterListViewController.swift +++ b/examples/iOS/FilterShowcase/FilterShowcaseSwift/FilterListViewController.swift @@ -7,7 +7,7 @@ class FilterListViewController: UITableViewController { // #pragma mark - Segues - override func prepare(for segue: UIStoryboardSegue, sender: Any?){ + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "showDetail" { if let indexPath = self.tableView.indexPathForSelectedRow { let filterInList = filterOperations[(indexPath as NSIndexPath).row] @@ -27,12 +27,14 @@ class FilterListViewController: UITableViewController { return filterOperations.count } - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) + -> UITableViewCell + { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) - let filterInList:FilterOperationInterface = filterOperations[(indexPath as NSIndexPath).row] + let filterInList: FilterOperationInterface = filterOperations[ + (indexPath as NSIndexPath).row] cell.textLabel?.text = filterInList.listName return cell } } - diff --git a/examples/iOS/SimpleImageFilter/SimpleImageFilter/AppDelegate.swift b/examples/iOS/SimpleImageFilter/SimpleImageFilter/AppDelegate.swift index bbaabe32..8bcf44eb 100644 --- a/examples/iOS/SimpleImageFilter/SimpleImageFilter/AppDelegate.swift +++ b/examples/iOS/SimpleImageFilter/SimpleImageFilter/AppDelegate.swift @@ -5,8 +5,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey:Any]?) -> Bool { + func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? + ) -> Bool { return true } } - diff --git a/examples/iOS/SimpleImageFilter/SimpleImageFilter/ViewController.swift b/examples/iOS/SimpleImageFilter/SimpleImageFilter/ViewController.swift index f2a2d90e..e0f5e606 100644 --- a/examples/iOS/SimpleImageFilter/SimpleImageFilter/ViewController.swift +++ b/examples/iOS/SimpleImageFilter/SimpleImageFilter/ViewController.swift @@ -1,35 +1,35 @@ -import UIKit import GPUImage +import UIKit class ViewController: UIViewController { - + @IBOutlet weak var renderView: RenderView! - var picture:PictureInput! - var filter:SaturationAdjustment! - + var picture: PictureInput! + var filter: SaturationAdjustment! + override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() - + // Filtering image for saving - let testImage = UIImage(named:"WID-small.jpg")! + let testImage = UIImage(named: "WID-small.jpg")! let toonFilter = ToonFilter() let filteredImage = testImage.filterWithOperation(toonFilter) - + let pngImage = UIImagePNGRepresentation(filteredImage)! do { - let documentsDir = try FileManager.default.url(for:.documentDirectory, in:.userDomainMask, appropriateFor:nil, create:true) - let fileURL = URL(string:"test.png", relativeTo:documentsDir)! - try pngImage.write(to:fileURL, options:.atomic) + let documentsDir = try FileManager.default.url( + for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) + let fileURL = URL(string: "test.png", relativeTo: documentsDir)! + try pngImage.write(to: fileURL, options: .atomic) } catch { print("Couldn't write to file with error: \(error)") } - + // Filtering image for display - picture = PictureInput(image:UIImage(named:"WID-small.jpg")!) + picture = PictureInput(image: UIImage(named: "WID-small.jpg")!) filter = SaturationAdjustment() picture --> filter --> renderView picture.processImage() } } - diff --git a/examples/iOS/SimpleMovieFilter/SimpleMovieFilter/AppDelegate.swift b/examples/iOS/SimpleMovieFilter/SimpleMovieFilter/AppDelegate.swift index bbaabe32..8bcf44eb 100644 --- a/examples/iOS/SimpleMovieFilter/SimpleMovieFilter/AppDelegate.swift +++ b/examples/iOS/SimpleMovieFilter/SimpleMovieFilter/AppDelegate.swift @@ -5,8 +5,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey:Any]?) -> Bool { + func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? + ) -> Bool { return true } } - diff --git a/examples/iOS/SimpleMovieFilter/SimpleMovieFilter/ViewController.swift b/examples/iOS/SimpleMovieFilter/SimpleMovieFilter/ViewController.swift index 173b6b8a..6b0e975c 100644 --- a/examples/iOS/SimpleMovieFilter/SimpleMovieFilter/ViewController.swift +++ b/examples/iOS/SimpleMovieFilter/SimpleMovieFilter/ViewController.swift @@ -1,21 +1,21 @@ -import UIKit import GPUImage +import UIKit class ViewController: UIViewController { - + @IBOutlet weak var renderView: RenderView! - - var movie:MovieInput! - var filter:Pixellate! - + + var movie: MovieInput! + var filter: Pixellate! + override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() - + let bundleURL = Bundle.main.resourceURL! - let movieURL = URL(string:"sample_iPod.m4v", relativeTo:bundleURL)! - + let movieURL = URL(string: "sample_iPod.m4v", relativeTo: bundleURL)! + do { - movie = try MovieInput(url:movieURL, playAtActualSpeed:true) + movie = try MovieInput(url: movieURL, playAtActualSpeed: true) filter = Pixellate() movie --> filter --> renderView movie.runBenchmark = true @@ -24,9 +24,8 @@ class ViewController: UIViewController { print("Couldn't process movie with error: \(error)") } -// let documentsDir = try NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain:.UserDomainMask, appropriateForURL:nil, create:true) -// let fileURL = NSURL(string:"test.png", relativeToURL:documentsDir)! -// try pngImage.writeToURL(fileURL, options:.DataWritingAtomic) + // let documentsDir = try NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain:.UserDomainMask, appropriateForURL:nil, create:true) + // let fileURL = NSURL(string:"test.png", relativeToURL:documentsDir)! + // try pngImage.writeToURL(fileURL, options:.DataWritingAtomic) } } - diff --git a/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/AppDelegate.swift b/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/AppDelegate.swift index ecede7fe..e1140fbd 100644 --- a/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/AppDelegate.swift +++ b/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/AppDelegate.swift @@ -5,8 +5,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? + ) -> Bool { // Override point for customization after application launch. return true } @@ -33,6 +35,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } - } - diff --git a/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/ViewController.swift b/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/ViewController.swift index 11b3e7a0..cf658ce8 100644 --- a/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/ViewController.swift +++ b/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/ViewController.swift @@ -1,18 +1,18 @@ -import UIKit import GPUImage +import UIKit class ViewController: UIViewController { - + @IBOutlet weak var renderView: RenderView! - var camera:Camera! - var operation:BrightnessAdjustment! - + var camera: Camera! + var operation: BrightnessAdjustment! + override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. - + do { -// operation = BasicOperation(fragmentFunctionName: "passthroughFragment") + // operation = BasicOperation(fragmentFunctionName: "passthroughFragment") operation = BrightnessAdjustment() camera = try Camera(sessionPreset: .vga640x480) camera.runBenchmark = true @@ -32,6 +32,5 @@ class ViewController: UIViewController { guard let slider = sender as? UISlider else { return } operation.brightness = slider.value } - -} +} diff --git a/examples/iOS/SimpleVideoRecorder/SimpleVideoRecorder/AppDelegate.swift b/examples/iOS/SimpleVideoRecorder/SimpleVideoRecorder/AppDelegate.swift index 42d77a48..8bcf44eb 100644 --- a/examples/iOS/SimpleVideoRecorder/SimpleVideoRecorder/AppDelegate.swift +++ b/examples/iOS/SimpleVideoRecorder/SimpleVideoRecorder/AppDelegate.swift @@ -5,7 +5,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey:Any]?) -> Bool { return true + func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? + ) -> Bool { + return true } } - diff --git a/examples/iOS/SimpleVideoRecorder/SimpleVideoRecorder/ViewController.swift b/examples/iOS/SimpleVideoRecorder/SimpleVideoRecorder/ViewController.swift index 7d27b94d..17ea0aca 100644 --- a/examples/iOS/SimpleVideoRecorder/SimpleVideoRecorder/ViewController.swift +++ b/examples/iOS/SimpleVideoRecorder/SimpleVideoRecorder/ViewController.swift @@ -1,19 +1,19 @@ -import UIKit -import GPUImage import AVFoundation +import GPUImage +import UIKit class ViewController: UIViewController { @IBOutlet weak var renderView: RenderView! - var camera:Camera! - var filter:SaturationAdjustment! + var camera: Camera! + var filter: SaturationAdjustment! var isRecording = false - var movieOutput:MovieOutput? = nil + var movieOutput: MovieOutput? = nil override func viewDidLoad() { super.viewDidLoad() - + do { - camera = try Camera(sessionPreset:.vga640x480) + camera = try Camera(sessionPreset: .vga640x480) camera.runBenchmark = true filter = SaturationAdjustment() camera --> filter --> renderView @@ -22,24 +22,26 @@ class ViewController: UIViewController { fatalError("Could not initialize rendering pipeline: \(error)") } } - + override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() } - + @IBAction func capture(_ sender: AnyObject) { - if (!isRecording) { + if !isRecording { do { self.isRecording = true - let documentsDir = try FileManager.default.url(for:.documentDirectory, in:.userDomainMask, appropriateFor:nil, create:true) - let fileURL = URL(string:"test.mp4", relativeTo:documentsDir)! + let documentsDir = try FileManager.default.url( + for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) + let fileURL = URL(string: "test.mp4", relativeTo: documentsDir)! do { - try FileManager.default.removeItem(at:fileURL) + try FileManager.default.removeItem(at: fileURL) } catch { } - - movieOutput = try MovieOutput(URL:fileURL, size:Size(width:480, height:640), liveVideo:true) -// camera.audioEncodingTarget = movieOutput + + movieOutput = try MovieOutput( + URL: fileURL, size: Size(width: 480, height: 640), liveVideo: true) + // camera.audioEncodingTarget = movieOutput filter --> movieOutput! movieOutput!.startRecording() DispatchQueue.main.async { @@ -50,12 +52,12 @@ class ViewController: UIViewController { fatalError("Couldn't initialize movie, error: \(error)") } } else { - movieOutput?.finishRecording{ + movieOutput?.finishRecording { self.isRecording = false DispatchQueue.main.async { (sender as! UIButton).titleLabel!.text = "Record" } -// self.camera.audioEncodingTarget = nil + // self.camera.audioEncodingTarget = nil self.movieOutput = nil } }