BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.2k stars 4.61k forks source link

There is no way to update image that inside of GPUImagePicture? #2614

Closed bang9 closed 5 years ago

bang9 commented 5 years ago

I have more than a dozen pictures(It is not video, just continuous image), and I can change these pictures through the thumbnail slider. (when changed position of thumbnail slider, picture will be changed)

I show up picture like this

GPUImagePicture -> levelsFilter -> whiteBalanceFilter -> GPUImageView

The image changes with the sliding speed. so I just changed image like this (while sliding on every frames)

// create a new GPUImagePicture every frame
let newImage = getCurrentFrameImage()

DispatchQueue.main.async {
    self._imageSource?.removeAllTargets()
    self._imageSource = GPUImagePicture(image: newImage)
    self._imageSource?.addTarget(_levelsFilter)
    self._imageSource?.processImage()
}

It works, but cause stuck of slider ui(when create a new GPUImagePicture object) For this reason, I tried replace main queue with global queue and sliding smoothly very well but It crash when sliding fast..

2019-03-06 17:46:31.594400+0900 -[1616:71356] *** Assertion failure in -[GPUImageFramebuffer unlock], /Users/bang9/Desktop/app/Carthage/Checkouts/GPUImage/framework/Source/GPUImageFramebuffer.m:269
2019-03-06 17:46:31.598557+0900 -[1616:71356] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to overrelease a framebuffer, did you forget to call -useNextFrameForImageCapture before using -imageFromCurrentFramebuffer?'

There is no way to change image data in GPUImagePicture?

bang9 commented 5 years ago

I solved problem like this

GPUImageRawDataInput -> levelsFilter -> whiteBalanceFilter -> GPUImageView
// Just update GPUImageRawDataInput data on every frame
// imageSource = GPUImageRawDataInput(...)

let newImage = getCurrentFrameImage()

DispatchQueue.main.async {
    let imageData = newImage.cgImage?.dataProvider?.data
    let imageBytes = UnsafeMutablePointer(mutating: CFDataGetBytePtr(dataFromImageDataProvider))
    //need to imageBytes convert RGBA to BGRA, I use opencv
    self._imageSource.updateData(fromBytes: UnsafeMutablePointer<GLubyte>(imageBytes), size: newImage.size)
    self._imageSource.processData()
}
hezhk3 commented 5 years ago

There's a category named "GPUImagePicture+TextureSubimage.h", you can also use this to update the image.