Skip to content

Add a Filter or Effect

Some design blocks in CE.SDK such as pages and graphic blocks allow you to add effects to them. An effect can modify the visual output of a block’s fill. CreativeEditor SDK supports many different types of effects, such as adjustments, LUT filters, pixelization, glow, vignette and more.

Similarly to blocks, each effect instance has a numeric id which can be used to query and modify its properties.

We create a scene containing a graphic block with an image fill and want to apply effects to this image.

let scene = try engine.scene.create()
let page = try engine.block.create(.page)
try engine.block.setWidth(page, value: 800)
try engine.block.setHeight(page, value: 600)
try engine.block.appendChild(to: scene, child: page)
try await engine.scene.zoom(to: page, paddingLeft: 40, paddingTop: 40, paddingRight: 40, paddingBottom: 40)
let block = try engine.block.create(.graphic)
try engine.block.setShape(block, shape: engine.block.createShape(.rect))
try engine.block.setPositionX(block, value: 100)
try engine.block.setPositionY(block, value: 50)
try engine.block.setWidth(block, value: 300)
try engine.block.setHeight(block, value: 300)
try engine.block.appendChild(to: page, child: block)
let fill = try engine.block.createFill(.image)
try engine.block.setString(
fill,
property: "fill/image/imageFileURI",
value: "https://img.ly/static/ubq_samples/sample_1.jpg"
)
try engine.block.setFill(block, fill: fill)

Accessing Effects

Not all types of design blocks support effects, so you should always first call the func supportsEffects(_ id: DesignBlockID) throws -> Bool API before accessing any of the following APIs.

try engine.block.supportsEffects(scene) // Returns false
try engine.block.supportsEffects(block) // Returns true

Creating an Effect

In order to add effects to our block, we first have to create a new effect instance, which we can do by calling func createEffect(_ type: EffectType) throws -> DesignBlockID and passing it the type of effect that we want. In this example, we create a pixelization and an adjustment effect.

Please refer to API Docs for a complete list of supported effect types.

let pixelize = try engine.block.createEffect(.pixelize)
let adjustments = try engine.block.createEffect(.adjustments)

Adding Effects

Now we have two effects but the output of our scene looks exactly the same as before. That is because we still need to append these effects to the graphic design block’s list of effects, which we can do by calling func appendEffect(_ id: DesignBlockID, effectID: DesignBlockID) throws.

We can also insert or remove effects from specific indices of a block’s effect list using the func insertEffect(_ id: DesignBlockID, effectID: DesignBlockID, index: Int) throws and func removeEffect(_ id: DesignBlockID, index: Int) throws APIs.

Effects will be applied to the block in the order they are placed in the block’s effects list. If the same effect appears multiple times in the list, it will also be applied multiple times. In our case, the adjustments effect will be applied to the image first, before the result of that is then pixelated.

try engine.block.appendEffect(block, effectID: pixelize)
try engine.block.insertEffect(block, effectID: adjustments, index: 0)
// try engine.block.removeEffect(rect, index: 0)

Querying Effects

Use the func getEffects(_ id: DesignBlockID) throws -> [DesignBlockID] API to query the ordered list of effect ids of a block.

// This will return [adjustments, pixelize]
let effectsList = try engine.block.getEffects(block)

Destroying Effects

If we created an effect that we don’t want anymore, we have to make sure to destroy it using the same func destroy(_ id: DesignBlockID) throws API that we also call for design blocks.

Effects that are attached to a design block will be automatically destroyed when the design block is destroyed.

let unusedEffect = try engine.block.createEffect(.halfTone)
try engine.block.destroy(unusedEffect)

Effect Properties

Just like design blocks, effects with different types have different properties that you can query and modify via the API. Use func findAllProperties(_ id: DesignBlockID) throws -> [String] in order to get a list of all properties of a given effect.

Please refer to the API Docs for a complete list of all available properties for each type of effect.

let allPixelizeProperties = try engine.block.findAllProperties(pixelize)
let allAdjustmentProperties = try engine.block.findAllProperties(adjustments)

Once we know the property keys of an effect, we can use the same APIs as for design blocks in order to modify those properties.

Our adjustment effect here for example will not modify the output unless we at least change one of its adjustment properties - such as the brightness - to not be zero.

try engine.block.setInt(pixelize, property: "pixelize/horizontalPixelSize", value: 20)
try engine.block.setFloat(adjustments, property: "effect/adjustments/brightness", value: 0.2)

Disabling Effects

You can temporarily disable and enable the individual effects using the func setEffectEnabled(effectID: DesignBlockID, enabled: Bool) throws API. When the effects are applied to a block, all disabled effects are simply skipped. Whether an effect is currently enabled or disabled can be queried with func isEffectEnabled(effectID: DesignBlockID) throws -> Bool.

try engine.block.setEffectEnabled(effectID: pixelize, enabled: false)
try engine.block.setEffectEnabled(effectID: pixelize, enabled: !engine.block.isEffectEnabled(effectID: pixelize))

Full Code

Here’s the full code:

import Foundation
import IMGLYEngine
@MainActor
func usingEffects(engine: Engine) async throws {
let scene = try engine.scene.create()
let page = try engine.block.create(.page)
try engine.block.setWidth(page, value: 800)
try engine.block.setHeight(page, value: 600)
try engine.block.appendChild(to: scene, child: page)
try await engine.scene.zoom(to: page, paddingLeft: 40, paddingTop: 40, paddingRight: 40, paddingBottom: 40)
let block = try engine.block.create(.graphic)
try engine.block.setShape(block, shape: engine.block.createShape(.rect))
try engine.block.setPositionX(block, value: 100)
try engine.block.setPositionY(block, value: 50)
try engine.block.setWidth(block, value: 300)
try engine.block.setHeight(block, value: 300)
try engine.block.appendChild(to: page, child: block)
let fill = try engine.block.createFill(.image)
try engine.block.setString(
fill,
property: "fill/image/imageFileURI",
value: "https://img.ly/static/ubq_samples/sample_1.jpg"
)
try engine.block.setFill(block, fill: fill)
try engine.block.supportsEffects(scene) // Returns false
try engine.block.supportsEffects(block) // Returns true
let pixelize = try engine.block.createEffect(.pixelize)
let adjustments = try engine.block.createEffect(.adjustments)
try engine.block.appendEffect(block, effectID: pixelize)
try engine.block.insertEffect(block, effectID: adjustments, index: 0)
// try engine.block.removeEffect(rect, index: 0)
// This will return [adjustments, pixelize]
let effectsList = try engine.block.getEffects(block)
let unusedEffect = try engine.block.createEffect(.halfTone)
try engine.block.destroy(unusedEffect)
let allPixelizeProperties = try engine.block.findAllProperties(pixelize)
let allAdjustmentProperties = try engine.block.findAllProperties(adjustments)
try engine.block.setInt(pixelize, property: "pixelize/horizontalPixelSize", value: 20)
try engine.block.setFloat(adjustments, property: "effect/adjustments/brightness", value: 0.2)
try engine.block.setEffectEnabled(effectID: pixelize, enabled: false)
try engine.block.setEffectEnabled(effectID: pixelize, enabled: !engine.block.isEffectEnabled(effectID: pixelize))
}