mrousavy / vision-camera-resize-plugin

A VisionCamera Frame Processor plugin for fast buffer resizing and colorspace (YUV <> RGBA) conversions
https://mrousavy.com
MIT License
74 stars 17 forks source link

Question about return of resize #38

Open SamuelAlv3s opened 4 months ago

SamuelAlv3s commented 4 months ago

Hello!

It's possible resize/crop a frame and return as the same type "Frame" instead a "Uint8Array" or "Float32Array" ?😬

mrousavy commented 4 months ago

Hey!

I would love to return a Frame instead of a byte array, but this isn't as easy as it sounds.

Overall it would definitely be a cooler API to return Frames, but Android's Media APIs don't allow this, as of now they are simply not as good/flexible as iOS' APIs.


For now, you can still pass the returned type (Uint8Array or Float32Array) to other Frame Processor Plugins without issues:

const { resize } = useResizePlugin()
const examplePlugin = VisionCameraProxy.initFrameProcessorPlugin('example_plugin')

const frameProcessor = useFrameProcessor((frame) => {
  'worklet'
  const resized = resize(frame, { ... })
  const arrayBuffer = resized.buffer

  // pass original `frame` because it is required for FPs, but we can ignore it later
  examplePlugin.call(frame, {
    // pass resized frame as an ArrayBuffer argument
    resizedFrame: arrayBuffer
  })
}, [resize])

Then just read the array from the arguments and ignore the Frame type:

@objc(ExampleFrameProcessorPlugin)
public class ExampleFrameProcessorPlugin: FrameProcessorPlugin {
  public override func callback(_ frame: Frame, withArguments arguments: [AnyHashable: Any]?) -> Any? {
    // we ignore `frame` as this is the full sized Frame

    // SharedArray is from VisionCamera
    let smallFrame = arguments["resizedFrame"] as SharedArray
    smallFrame.data // <-- access
  }
}
SamuelAlv3s commented 4 months ago

Nice!!

Thanks for the answer😁

mrousavy commented 4 months ago

Let's leave this open for now, maybe in the future there's gonna be an API in Android to create a pool of Images where I can have ownership of the memory without needing a Surface - that'd solve the problem of ImageWriter then!