PyO3/rust-numpy

Example for image I/O ?

melMass opened this issue · 3 comments

Hi,

I'm familiar with pyo3 but I'm hitting a road block when trying to do I/O between rust images (image crate buffers or anything) and numpy arrays.

Any help is appreciated.

Thanks

I suspect the main insight here is that you need to target ndarray as an intermediate format between image buffers and NumPy arrays. There are crates dedicated to that interface, c.f. nshare or ndarray-ndimage.

If that helps maybe you could contribute an example using one of these crates here?

Thanks nshare definitely seems like it has the answers I was looking for, I will try tomorrow and report here.
And I'm definitely up to PR a sample for that, I've wondered before.

It's working! I've use nshare

Probably not the most efficient but this work:

use nshare::ToNdarray3;

 fn render(&self, py: Python<'_>) -> PyResult<Vec<Py<PyArray3<u8>>>> {
        // ...
        
        // .. Frame is an enum wrapping image::ImageBuffers by bitdepth
        let frames: Vec<&Frame> = renderer.frames.iter().collect();

        let frames: Vec<Py<PyArray3<u8>>> = renderer
            .frames
            .iter()
            .map(|f| match f {
                Frame::U8(frame) => frame.clone().into_ndarray3().to_pyarray(py).to_owned(),
                _ => panic!("not u8"),
            })
            .collect();

        Ok(frames)
    }

And in python

from PIL import Image
import engine

arr = engine.render()

first = np.transpose(arr[0], (1,2,0))

image = Image.fromarray(first)