Code Monkey home page Code Monkey logo

Comments (7)

pennywise94 avatar pennywise94 commented on May 19, 2024 1

You must have understood me wrong. When I change the value using a slider, this is my code:

@objc func changeFilterValue(_ slider: UISlider) {
    filterValue = slider.value / 100
    filterSliderLabel.text = "\(round(slider.value).clean)%"
    self.metalFilter?.intensity = filterValue
    if(imageSource != nil) {
        self.imageSource.transmitTexture()
    }
}

Which works perfectly fine, for images as well as for video. The update happens really fast. It's amazing. I only change the filter change when the user initiates a new lookup filter, like this:

if(imageSource != nil) {
    imageSource.removeAllConsumers()
    metalFilter?.removeAllConsumers()
    brightnessFilter?.removeAllConsumers()
    if(currentFilter == 0) {
        metalFilter = nil
        self.brightnessFilter = BBMetalBrightnessFilter(brightness: self.brightnessValue)
        self.imageSource .add(consumer: brightnessFilter!)
            .add(consumer: metalView)
        self.imageSource.transmitTexture()
    } else {
        self.metalFilter = BBMetalLookupFilter(lookupTable: UIImage(named: "lookup_\(indexPath.item)")!.bb_metalTexture!)
        self.brightnessFilter = BBMetalBrightnessFilter(brightness: self.brightnessValue)
        self.imageSource.add(consumer: brightnessFilter!)
            .add(consumer: metalFilter!)
            .add(consumer: metalView)
        self.imageSource.transmitTexture()
    }
} else if(currentVideoURL != nil) {
    if(!isFiltering) {
        videoSource.removeAllConsumers()
        metalFilter?.removeAllConsumers()
        brightnessFilter?.removeAllConsumers()
        if(indexPath.item == 0) {
            videoSource.add(consumer: metalView)
        } else {
            self.metalFilter = BBMetalLookupFilter(lookupTable: UIImage(named: "lookup_\(indexPath.item)")!.bb_metalTexture!)
            self.brightnessFilter = BBMetalBrightnessFilter(brightness: 0)
            videoSource.add(consumer: brightnessFilter!)
                .add(consumer: metalFilter!)
                .add(consumer: metalView)
        }
    }
}

filterValue = 1
filterSlider.setValue(100, animated: false)
filterSliderLabel.text = "100%"

This works really smooth too. All I still have to deal with now, is the synchronization of video and audio. Have been searching the Internet, looked into GPUImage (which deals with the same issue still, I feel like). Nowhere I can find a solution. But I think I'll just have to go with the temporary solution of using an AVPlayer and let it go out of sync. I'll fix it later when a solution comes up. Amazing library you have provided!

from bbmetalimage.

pennywise94 avatar pennywise94 commented on May 19, 2024

I feel like I'll be able to make it work by using the same method as I use for video. I would set up an imageSource, add my consumers and use a BBMetalView as last consumer. Then, I would transmit the texture using transmitTexture() when needed. Would this be a good solution, or would it consume too much resources? Can it be done more efficiently?

Also, if I go for this approach, how can I save the current MetalView (using the filters I have applied) as an image or get it as UIImage?

from bbmetalimage.

Silence-GitHub avatar Silence-GitHub commented on May 19, 2024

Setup filter chain first. Add completion callback to the last filter to update image view.

self.imageSource.add(consumer: self.lookupFilter)
    .add(consumer: self.brightnessFilter)
    .addCompletedHandler { [weak self] (_) in // Use weak self or there will be memory leak
        DispatchQueue.main.async {
            guard let self = self else { return }
            self.imageView.image = self.brightnessFilter.outputTexture?.bb_image
        }
}

When changing the slider value, update filter value and transmit texture. Do not change the filter chain here.

self.lookupFilter.intensity = slider.value
self.brightnessFilter.brightness = slider2.value
self.imageSource.transmitTexture()

from bbmetalimage.

pennywise94 avatar pennywise94 commented on May 19, 2024

Been trying this, but I have trouble updating the filter chain. I give users the ability to add filters (choose from 11 different LUTs), change brightness, contrast, ... so I remove all consumers when they change a LUT filter, and update the values when they change brightness, contrast etc.

This makes it for me impossible to just update the values and transmitTexture() like you suggest in the last piece of code. Instead, I use a metalView to show the image (just like video), which updates the consumers on the fly. Then, when I save the photo, I initiate a new filter chain with the current LUT (if any) and the values for brightness etc. are hold as variables. This works very well (and fast) now. Is this a suitable approach, specifically when removing and adding new consumers?

from bbmetalimage.

Silence-GitHub avatar Silence-GitHub commented on May 19, 2024

When changing the slider value, do not change the filter chain (You can setup the filter chain if not exists for the first time slider value changed). When changing the LUT filter, change the filter chain. Just like processing video. I guess the user can not change both LUT filter and slider value at the same time.

from bbmetalimage.

pennywise94 avatar pennywise94 commented on May 19, 2024

That's right. But when I use your suggested method, when I present the image in an imageView, the updates don't happen to my image. When I render a metalView, it does render immediately. Is there something I'm missing? Can I, at all, use the metalView or would you not recommend this for images?

from bbmetalimage.

Silence-GitHub avatar Silence-GitHub commented on May 19, 2024

Your solution is okay. I just think it unnecessary to update the filter chain when changing slider value.

from bbmetalimage.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.