From f7c026fbd3ceab3a2bf0595b8c3883f84bdeefd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 24 May 2023 20:46:38 +0200 Subject: [PATCH] python: expose image-to-image ImageConverter APIs as well. --- doc/python/magnum.trade.rst | 3 +++ package/ci/appveyor-desktop-gles.bat | 1 + package/ci/appveyor-desktop.bat | 1 + package/ci/unix-desktop-gles.sh | 1 + package/ci/unix-desktop.sh | 1 + src/python/magnum/test/test_trade.py | 28 +++++++++++++++++++++++++++- src/python/magnum/trade.cpp | 14 ++++++++++++++ 7 files changed, 48 insertions(+), 1 deletion(-) diff --git a/doc/python/magnum.trade.rst b/doc/python/magnum.trade.rst index be0e93a..f7d0110 100644 --- a/doc/python/magnum.trade.rst +++ b/doc/python/magnum.trade.rst @@ -539,6 +539,9 @@ raising an exception. See particular function documentation for detailed behavior. +.. py:function:: magnum.trade.AbstractImageConverter.convert + :raise RuntimeError: If image conversion fails + .. py:function:: magnum.trade.AbstractImageConverter.convert_to_file :raise RuntimeError: If image conversion fails diff --git a/package/ci/appveyor-desktop-gles.bat b/package/ci/appveyor-desktop-gles.bat index 1dbe498..548607b 100644 --- a/package/ci/appveyor-desktop-gles.bat +++ b/package/ci/appveyor-desktop-gles.bat @@ -86,6 +86,7 @@ cmake .. ^ -DMAGNUM_WITH_STANFORDSCENECONVERTER=ON ^ -DMAGNUM_WITH_STBIMAGECONVERTER=ON ^ -DMAGNUM_WITH_STBIMAGEIMPORTER=ON ^ + -DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON ^ -DMAGNUM_WITH_STBTRUETYPEFONT=ON ^ -G Ninja || exit /b cmake --build . || exit /b diff --git a/package/ci/appveyor-desktop.bat b/package/ci/appveyor-desktop.bat index 116ee84..fff811f 100644 --- a/package/ci/appveyor-desktop.bat +++ b/package/ci/appveyor-desktop.bat @@ -96,6 +96,7 @@ cmake .. ^ -DMAGNUM_WITH_STANFORDSCENECONVERTER=ON ^ -DMAGNUM_WITH_STBIMAGECONVERTER=ON ^ -DMAGNUM_WITH_STBIMAGEIMPORTER=ON ^ + -DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON ^ -DMAGNUM_WITH_STBTRUETYPEFONT=ON ^ %COMPILER_EXTRA% -G Ninja || exit /b cmake --build . || exit /b diff --git a/package/ci/unix-desktop-gles.sh b/package/ci/unix-desktop-gles.sh index e3c5219..223edac 100755 --- a/package/ci/unix-desktop-gles.sh +++ b/package/ci/unix-desktop-gles.sh @@ -73,6 +73,7 @@ cmake .. \ -DMAGNUM_WITH_STANFORDSCENECONVERTER=ON \ -DMAGNUM_WITH_STBIMAGECONVERTER=ON \ -DMAGNUM_WITH_STBIMAGEIMPORTER=ON \ + -DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON \ -DMAGNUM_WITH_STBTRUETYPEFONT=ON \ -G Ninja ninja install diff --git a/package/ci/unix-desktop.sh b/package/ci/unix-desktop.sh index 7d500b8..6fb1f5e 100755 --- a/package/ci/unix-desktop.sh +++ b/package/ci/unix-desktop.sh @@ -77,6 +77,7 @@ cmake .. \ -DMAGNUM_WITH_STANFORDSCENECONVERTER=ON \ -DMAGNUM_WITH_STBIMAGECONVERTER=ON \ -DMAGNUM_WITH_STBIMAGEIMPORTER=ON \ + -DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON \ -DMAGNUM_WITH_STBTRUETYPEFONT=ON \ -G Ninja ninja install diff --git a/src/python/magnum/test/test_trade.py b/src/python/magnum/test/test_trade.py index f472146..cb34c82 100644 --- a/src/python/magnum/test/test_trade.py +++ b/src/python/magnum/test/test_trade.py @@ -1645,10 +1645,36 @@ class ImageConverter(unittest.TestCase): converter.flags = trade.ImageConverterFlags.VERBOSE self.assertEqual(converter.flags, trade.ImageConverterFlags.VERBOSE) + # TODO test also 1D and 3D variants for more robustness + def test_image2d(self): importer = trade.ImporterManager().load_and_instantiate('StbImageImporter') importer.open_file(os.path.join(os.path.dirname(__file__), 'rgb.png')) image = importer.image2d(0) + self.assertEqual(image.size, Vector2i(3, 2)) + + converter = trade.ImageConverterManager().load_and_instantiate('StbResizeImageConverter') + converter.configuration['size'] = "1 1" + + converted = converter.convert(image) + self.assertEqual(converted.size, Vector2i(1, 1)) + + def test_image2d_failed(self): + importer = trade.ImporterManager().load_and_instantiate('StbImageImporter') + importer.open_file(os.path.join(os.path.dirname(__file__), 'rgb.png')) + image = importer.image2d(0) + self.assertEqual(image.size, Vector2i(3, 2)) + + converter = trade.ImageConverterManager().load_and_instantiate('StbResizeImageConverter') + # not setting any size + + with self.assertRaisesRegex(RuntimeError, "conversion failed"): + converter.convert(image) + + def test_image2d_to_file(self): + importer = trade.ImporterManager().load_and_instantiate('StbImageImporter') + importer.open_file(os.path.join(os.path.dirname(__file__), 'rgb.png')) + image = importer.image2d(0) converter = trade.ImageConverterManager().load_and_instantiate('StbImageConverter') @@ -1656,7 +1682,7 @@ class ImageConverter(unittest.TestCase): converter.convert_to_file(image, os.path.join(tmp, "image.png")) self.assertTrue(os.path.exists(os.path.join(tmp, "image.png"))) - def test_image2d_failed(self): + def test_image2d_to_file_failed(self): importer = trade.ImporterManager().load_and_instantiate('StbImageImporter') importer.open_file(os.path.join(os.path.dirname(__file__), 'rgb.png')) image = importer.image2d(0) diff --git a/src/python/magnum/trade.cpp b/src/python/magnum/trade.cpp index 96794fc..26470df 100644 --- a/src/python/magnum/trade.cpp +++ b/src/python/magnum/trade.cpp @@ -447,6 +447,17 @@ template(Trade::AbstractImporter::*f)(UnsignedI /* Can't be named just checkResult() because the AbstractSceneConverter overload would confuse GCC 4.8 */ +template(Trade::AbstractImageConverter::*f)(const T&)> R checkImageConverterResult(Trade::AbstractImageConverter& self, const T& image) { + /** @todo log redirection -- but we'd need assertions to not be part of + that so when it dies, the user can still see why */ + Containers::Optional out = (self.*f)(image); + if(!out) { + PyErr_SetString(PyExc_RuntimeError, "conversion failed"); + throw py::error_already_set{}; + } + + return *std::move(out); +} /** @todo drop std::string in favor of our own string caster */ template void checkImageConverterResult(Trade::AbstractImageConverter& self, const T& image, const std::string& filename) { /** @todo log redirection -- but we'd need assertions to not be part of @@ -1678,6 +1689,9 @@ void trade(py::module_& m) { }, [](Trade::AbstractImageConverter& self, Trade::ImageConverterFlag flags) { self.setFlags(flags); }, "Converter flags") + .def("convert", checkImageConverterResult, "Convert a 1D image", py::arg("image")) + .def("convert", checkImageConverterResult, "Convert a 2D image", py::arg("image")) + .def("convert", checkImageConverterResult, "Convert a 3D image", py::arg("image")) .def("convert_to_file", checkImageConverterResult, "Convert a 1D image to a file", py::arg("image"), py::arg("filename")) .def("convert_to_file", checkImageConverterResult, "Convert a 2D image to a file", py::arg("image"), py::arg("filename")) .def("convert_to_file", checkImageConverterResult, "Convert a 3D image to a file", py::arg("image"), py::arg("filename"));