microsoft / xlang

MIT License
877 stars 103 forks source link

Pass variable by reference to method #748

Closed lookforward-github closed 3 years ago

lookforward-github commented 3 years ago

I'm trying to create application to work with infrared camera.

I'm using pywinrt to get access to camera and Tkinter to render picture as bitmap. In one moment I have to get data buffer from frame reader and I have to pass variable by reference to retrieve it. But Python cant work with references.

My code:

frame = frame_reader.try_acquire_latest_frame() # frame is MediaFrameReference
# https://docs.microsoft.com/en-us/uwp/api/windows.media.capture.frames.mediaframereference
if frame:
    video_frame = frame.video_media_frame
    software_bitmap = video_frame.software_bitmap
    if software_bitmap:
        buff = None # buffer data var
        software_bitmap.copy_to_buffer(buff) # trying to pass by reference as described in API
        # https://docs.microsoft.com/en-us/uwp/api/windows.graphics.imaging.softwarebitmap.copytobuffer

Error message:

File ".\test.py", line 56, in get_frame
  software_bitmap.copy_to_buffer(buff)
RuntimeError: Параметр задан неверно.

How I should correct pass variable?

jonwis commented 3 years ago

That method takes an existing buffer into which it'll write data. See:

https://github.com/microsoft/Windows-universal-samples/blob/b1cb20f191d3fd99ce89df50c5b7d1a6e2382c01/Samples/BasicFaceDetection/cs/Scenario1_DetectInPhoto.xaml.cs#L168-L169

If you aren't using XAML's WriteableBitmap you'll need to compute the size of the buffer from the bitmap.

You can also try SoftwareBitmap.LockBuffer, which gets you direct access to the frame of data without making a copy.

lookforward-github commented 3 years ago

Thank you, jonwis. If I use SoftwareBitmap.LockBuffer I have to cast MemoryByffer to IMemoryBufferByteAccess. But I dont know where I can find class which implements this interface or how can I cast MemoryBuffer or MemoryBufferReference to it in Python.

WritebaleBitmap is not available due to I cannot import system.windows.media.imaging

ModuleNotFoundError: No module named 'system' # import system.windows.media.imaging
ModuleNotFoundError: No module named 'winrt.system' # import winrt.system.windows.media.imaging
ModuleNotFoundError: No module named 'winrt.windows.media.imaging' # import winrt.windows.media.imaging
jonwis commented 3 years ago

I meant the Windows.UI.Xaml.Media.Imaging.WriteableBitmap type, sorry. @dlech has #743 which adds buffer support; maybe that needs to be expanded to include IMemoryBuffer?

dlech commented 3 years ago

FYI, https://github.com/microsoft/cppwinrt/pull/956 is required for accessing the buffer from IMemoryBuffer.

dlech commented 3 years ago

You can find a test build that implements the CPython buffer protocol on IMemoryBufferReference at https://github.com/dlech/xlang/actions/runs/932253215. Let me know if that works for you.