SessionFilter

@objcMembers
open class SessionFilter : Codable

The SessionFilter class is designed to be subclassed. Without a subclass it simply acts as a passthrough filter. Each session filter manages the allocation of its respective GPUImage3 operation (lookup filter, brightness adjustment, etc.) and keeps that operation up-to-date during user interaction from the intensity slider. The operation is responsible for the manipulation of the video frame or image. Session filters also contain UI information such as their display name, thumbnail images and a view controller. In addition, they are codable allowing for their state to be saved.

See the tutorial on how to create a custom session filter using Photoshop. A simple and complex implementation of a custom session filter is also included in the sample code.

Subclassing

You must override the operation() function so it returns a freshly allocated GPUImage3 operation of your choosing. You must also override the operationUpdateNeeded(_:) function so it updates the state of your operation. When there is user interaction with the intensity slider the operationUpdateNeeded(_:) function will be called. You must then set the intensity of your operation using the current intensity value of the slider. Since every operation is different and the number of operations used is up to you, it is your responsibility to tell your operation how to react when the intensity slider is adjusted. Below is an example of overriding these functions:

override public func operation() -> ImageProcessingOperation {
    return BrightnessAdjustment()
}
override public func operationUpdateNeeded(_ op: ImageProcessingOperation) {
    let op = op as! BrightnessAdjustment

    op.brightness = Float(self.actualIntensity)
}

Some work has been done to make translating values from the intensity slider to the operation easier. The intensity slider uses values of “normalized intensity” whereas the operation uses values of “actual intensity”. Since many operations use values that are not visually pleasing they get translated to normalized values for the UI. When the intensity slider is adjusted, the normalizedIntensity variable will be updated, operationUpdateNeeded(_:) will be called, and you can then use the actualIntensity variable (which is calculated from the normalizedIntensity variable) to update your operation. This works by converting a number of one range to another range.

Adjust filters found in the Adjust tab of the EditController will usually have normalized intensity values in the range of -1.0 to 1.0 whereas primary filters found in the Filter tab of the EditController and on the CameraController will have normalized intensity values in the range of 0 to 100. It is your responsibility to set the ranges for both the normalized and actual values in your session filter initializers. You must also set the initial position of the slider, by setting the actualIntensityDefault variable.

User Interface

You can provide your own UIViewController for the session filter by overriding the viewController() function. The controller will be displayed when the filter is tapped on the Adjust tab or it is tapped twice on the Filter tab.

If you do not override the viewController() function, a default controller will be returned that contains a simple intensity slider.

Figure 1 Default view controller

Custom Controller

The controller you return from viewController() can optionally conform to the following protocols for added functionality:

BottomBarProvider: Allows you to provide a custom bottom bar that will be visible when your controller is visible. If you do not provide a bottom bar, the default Cancel/Done bottom bar will be used.

TopBarProvider: Allows you to provide a custom top bar that will be visible when your controller is visible. If you do not provide a top bar, the default top bar that shows your filter name will be used.

SessionFilterControllerAdditions: Enables access to helper functions for the dismissal of your controller.

Creating a SessionFilter

  • Creates a new SessionFilter.

    Declaration

    Swift

    public required init()

Encoding/Decoding a SessionFilter

  • Used for decoding a session filter. You should override this if you need to decode your own variables.

    You must call super when you override.

    Declaration

    Swift

    public required init(from decoder: Decoder) throws

    Parameters

    decoder

    The decoder.

  • Used for encoding a session filter. You should override this if you need to encode your own variables.

    You must call super when you override.

    Declaration

    Swift

    open func encode(to encoder: Encoder) throws

    Parameters

    encoder

    The encoder.

  • Returns a session filter created from the provided Data. The Data you provide must have come from the toData() function.

    The Decodable protocol and init(from decoder:) function are used to decode the Data.

    Declaration

    Swift

    public class func fromData(_ data: Data) throws -> SessionFilter

    Parameters

    data

    The data.

  • Returns Data that represents the current session filter.

    The Encodable protocol and encode(to encoder:) function are used to encode the Data.

    Declaration

    Swift

    public func toData() throws -> Data
  • Returns a copy of the current session filter using the Decodable and Encodable protocols.

    All this function does is return the following try SessionFilter.fromData(try self.toData())

    If the copy fails, an error is printed to the console and a passthrough SessionFilter() is returned.

    Declaration

    Swift

    public func copy() -> SessionFilter

Metadata

  • The display name of the filter. This will be displayed on the EditController and CameraController or just the EditController if this is an adjust filter.

    Default value: ""

    Declaration

    Swift

    public var displayName: String
  • The version of the filter. Use this for your own record keeping.

    Default value: nil

    Declaration

    Swift

    public var version: String?
  • Set this to true if your filter distorts its output. In other words, if the pixel positions are no longer a one to one mapping.

    This lets us know that we need to temporarily disable this filter when the user is on the cropping/positioning controller.

    Default value: false

    Declaration

    Swift

    public var distortsOutput: Bool

Thumbnails

  • This thumbnail will be displayed on the CameraController.

    The size of this image should be 40x40 points.

    Default value: nil

    Declaration

    Swift

    public var cameraThumbnailImage: UIImage?
  • This thumbnail will be displayed on the Adjust tab of the EditController.

    The size of this image should be 60x60 points.

    Default value: nil

    Declaration

    Swift

    public var adjustThumbnailImage: UIImage?

Intensity Values

  • True if the normalizedIntensity is not equal to the normalizedIntensityDefault.

    You can override this if you have other criteria that indicates if a filter is active.

    Declaration

    Swift

    open var isActive: Bool { get }
  • The current slider position.

    Default value: normalizedIntensityDefault

    Declaration

    Swift

    public var normalizedIntensity: Double { get set }
  • The default slider position.

    This is calculated from the actualIntensityDefault.

    Declaration

    Swift

    public var normalizedIntensityDefault: Double { get }
  • The range that the slider should use. The left side of the range will be the value on the left side of the slider and the right side of the range will be the value on the right side of the slider.

    Default value: (0, 100)

    Declaration

    Swift

    public var normalizedIntensityRange: (Double, Double)
  • The current intensity that should be used by your operation.

    This is calculated from the normalizedIntensity.

    Declaration

    Swift

    public var actualIntensity: Double { get }
  • The default intensity for your operation.

    Since normalizedIntensityDefault is calculated with this - the initial position of the slider is also determined with this variable.

    Default value: 1

    Declaration

    Swift

    public var actualIntensityDefault: Double
  • The intensity range that your operation should use.

    Default value: (0, 1)

    Declaration

    Swift

    public var actualIntensityRange: (Double, Double)

Operations

  • Must return a freshly allocated GPUImage3 operation. Your subclass must override this. For example:

    override public func operation() -> ImageProcessingOperation {
        return BrightnessAdjustment()
    }
    

    Declaration

    Swift

    open func operation() -> ImageProcessingOperation
  • Calling this will cause operationUpdateNeeded(_:) to be called once for every operation that has been returned by the operation() function. It will also forward a new framebuffer through those operations if necessary. Operations that have deallocated will not be included.

    Declaration

    Swift

    public func updateAllOperations()
  • This will be called whenever your operation needs to be updated. Your subclass must override this. You should use this time to take the value from the intensity slider and set it on your operation. For example:

    override public func operationUpdateNeeded(_ op: ImageProcessingOperation) {
        let op = op as! BrightnessAdjustment
    
        op.brightness = Float(self.actualIntensity)
    }
    

    Declaration

    Swift

    open func operationUpdateNeeded(_ op: ImageProcessingOperation)

    Parameters

    op

    The operation which needs updating. You should cast this to the type of operation you returned in operation().

User Interface

  • This can be overridden if you would like to provide a custom UIViewController for this SessionFilter.

    The controller will be displayed when the SessionFilter is tapped on the Adjust tab or the SessionFilter is tapped twice on the Filter tab.

    If you do not override, the default controller returned by this function contains a simple intensity slider.

    The controller you return can optionally conform to the following protocols for added functionality:

    BottomBarProvider: Allows you to provide a custom bottom bar that will be visible when your controller is visible. If you do not provide a bottom bar, the default Cancel/Done bottom bar will be used.

    TopBarProvider: Allows you to provide a custom top bar that will be visible when your controller is visible. If you do not provide a top bar, the default top bar that shows your filter name will be used.

    SessionFilterControllerAdditions: Enables access to helper functions for the dismissal of your controller.

    Custom Controller

    Declaration

    Swift

    open func viewController() -> UIViewController