Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added src/doc/figures/imagebuf-notebook-demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions src/doc/pythonbindings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4260,3 +4260,37 @@ add an alpha channel that is 1 everywhere**
out.open ("multipart.exr", specs[s], "AppendSubimage")
bufs[s].write (out)
out.close ()



Jupyter Notebooks
-----------------

Like any other Python package, OpenImageIO can be used in `Jupyter notebooks <https://jupyter.org/install>`_.
The ImageBuf objects support getting displayed inline within notebooks.

.. image:: figures/imagebuf-notebook-demo.png

.. warning::

Currently, ImageBuf objects get displayed as **uint8 PNGs** inside of notebooks.
ImageBuf objects that store images with higher bit depths get dithered to account for this.
Keep in mind that directly saving the inline image to disk will not preserve the original image within the ImageBuf.


Running a Local Jupyter Notebook
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you want to run a local Jupyter notebook with OpenImageIO, you can do so from within the Python environment in which you have installed OpenImageIO.

.. code-block:: bash

pip install jupyterlab
jupyter lab

Alternatively, if you prefer using `uv <https://github.com/astral-sh/uv>`_, you can run the following command:

.. code-block:: bash

uv run --with jupyter jupyter lab


31 changes: 31 additions & 0 deletions src/python/py_imagebuf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <memory>

#include <OpenImageIO/filesystem.h>
#include <OpenImageIO/platform.h>


Expand Down Expand Up @@ -250,6 +251,35 @@ ImageBuf_set_write_format(ImageBuf& self, const py::object& py_channelformats)



py::bytes
ImageBuf_repr_png(const ImageBuf& self)
{
ImageSpec original_spec = self.spec();

if (original_spec.width < 1 || original_spec.height < 1) {
return py::bytes();
}

// Alter the spec to make sure it dithers when outputting to 8 bit PNG
ImageSpec altered_spec = original_spec;
altered_spec.attribute("oiio:dither", 1);

std::vector<unsigned char> file_buffer; // bytes will go here
Filesystem::IOVecOutput file_vec(file_buffer); // I/O proxy object

std::unique_ptr<ImageOutput> out = ImageOutput::create("temp.png",
&file_vec);
out->open("temp.png", altered_spec);
self.write(out.get());
out->close();

// Cast to const char* and return as python bytes
const char* char_ptr = reinterpret_cast<const char*>(file_buffer.data());
return py::bytes(char_ptr, file_buffer.size());
}



void
declare_imagebuf(py::module& m)
{
Expand Down Expand Up @@ -491,6 +521,7 @@ declare_imagebuf(py::module& m)
.def(
"deepdata", [](ImageBuf& self) { return *self.deepdata(); },
py::return_value_policy::reference_internal)
.def("_repr_png_", &ImageBuf_repr_png)

// FIXME -- do we want to provide pixel iterators?
;
Expand Down
Binary file added testsuite/python-imagebuf/ref/invalid_repr_png.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added testsuite/python-imagebuf/ref/valid_repr_png.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion testsuite/python-imagebuf/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
outputs = [ "out.tif", "outtuple.tif",
"outarray.tif", "outarrayB.tif", "outarrayH.tif",
"perchan.exr", "multipart.exr",
"out.txt" ]
"out.txt", "valid_repr_png.png", "invalid_repr_png.png" ]

Binary file added testsuite/python-imagebuf/src/AllHalfValues.exr
Binary file not shown.
18 changes: 18 additions & 0 deletions testsuite/python-imagebuf/src/test_imagebuf.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@ def write (image, filename, format=oiio.UNKNOWN) :



def test_repr_png () :
# Test a valid 16 bit exr
b = oiio.ImageBuf("src/AllHalfValues.exr")
png = b._repr_png_()

with open("valid_repr_png.png", "wb") as f:
f.write(png)

# Test an invalid image with null dimensions
# create ImageBuf with x dimension as 0
b = oiio.ImageBuf(oiio.ImageSpec(0,2,4,"float"))
png = b._repr_png_()
with open("invalid_repr_png.png", "wb") as f:
f.write(png)



def test_perchannel_formats () :
# Test writing per-channel formats with an ImageBuf
b = oiio.ImageBuf(oiio.ImageSpec(2,2,4,"float"))
Expand Down Expand Up @@ -296,6 +313,7 @@ def test_copy_metadata() :
test_multiimage ()
test_uninitialized ()
test_copy_metadata ()
test_repr_png ()

print ("\nDone.")
except Exception as detail:
Expand Down
Loading