Silence-GitHub / BBMetalImage

A high performance Swift library for GPU-accelerated image/video processing based on Metal.
MIT License
988 stars 126 forks source link

How to chain blend and other overlays #26

Closed dougdot3 closed 4 years ago

dougdot3 commented 4 years ago

It's unclear to me how to combine 'regular' filters with two-image filters.

I've tried a number of things but keep getting errors.

For example, how to asynchronously:

Add an overlay blend filter. Use a brightness filter

If I try to take a blended image and then add brightness etc to it I get an error.

let blendedImage = BBMetalOverlayBlendFilter().filteredImage(with: imageToFilter, topBlendImage(withAlpha: 0.7))
 let imageSource = BBMetalStaticImageSource(image: blendedImage) // Throws error
Silence-GitHub commented 4 years ago

Get filtered image synchronously. You can do it in the background thread to make it async.

if let blendedImage = BBMetalOverlayBlendFilter().filteredImage(with: imageToFilter, topBlendImage(withAlpha: 0.7)),
    let image = BBMetalBrightnessFilter(brightness: 0.2).filteredImage(with: blendedImage) {
    // Do something with image
} else {
    // Handle nil
}

Get filtered image asynchronously.

// Hold image source
var source: BBMetalStaticImageSource!
var source2: BBMetalStaticImageSource!

func processImage() {
    // Set up filter chain
    source = BBMetalStaticImageSource(image: imageToFilter)
    source2 = BBMetalStaticImageSource(image: topBlendImage(withAlpha: 0.7))
    let blendFilter = BBMetalOverlayBlendFilter()
    let brightnessFilter = BBMetalBrightnessFilter(brightness: 0.2)
    source.add(consumer: blendFilter)
    source2.add(consumer: blendFilter)
        .add(consumer: brightnessFilter)
        .addCompletedHandler { [weak self] (_) in
            DispatchQueue.main.async {
                guard let self = self else { return }
                // Display filtered image
                self.imageView.image = brightnessFilter.outputTexture?.bb_image
            }
    }

    // Transmit texture
    source.transmitTexture()
    source2.transmitTexture()
}
dougdot3 commented 4 years ago

Thanks for such a detailed response. Your framework is magic. Have implemented in a SwiftUI project and it's working like a charm, but got stuck on this one!