Browse Source

python: expose image-to-image ImageConverter APIs as well.

next
Vladimír Vondruš 3 years ago
parent
commit
f7c026fbd3
  1. 3
      doc/python/magnum.trade.rst
  2. 1
      package/ci/appveyor-desktop-gles.bat
  3. 1
      package/ci/appveyor-desktop.bat
  4. 1
      package/ci/unix-desktop-gles.sh
  5. 1
      package/ci/unix-desktop.sh
  6. 28
      src/python/magnum/test/test_trade.py
  7. 14
      src/python/magnum/trade.cpp

3
doc/python/magnum.trade.rst

@ -539,6 +539,9 @@
raising an exception. See particular function documentation for detailed raising an exception. See particular function documentation for detailed
behavior. behavior.
.. py:function:: magnum.trade.AbstractImageConverter.convert
:raise RuntimeError: If image conversion fails
.. py:function:: magnum.trade.AbstractImageConverter.convert_to_file .. py:function:: magnum.trade.AbstractImageConverter.convert_to_file
:raise RuntimeError: If image conversion fails :raise RuntimeError: If image conversion fails

1
package/ci/appveyor-desktop-gles.bat

@ -86,6 +86,7 @@ cmake .. ^
-DMAGNUM_WITH_STANFORDSCENECONVERTER=ON ^ -DMAGNUM_WITH_STANFORDSCENECONVERTER=ON ^
-DMAGNUM_WITH_STBIMAGECONVERTER=ON ^ -DMAGNUM_WITH_STBIMAGECONVERTER=ON ^
-DMAGNUM_WITH_STBIMAGEIMPORTER=ON ^ -DMAGNUM_WITH_STBIMAGEIMPORTER=ON ^
-DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON ^
-DMAGNUM_WITH_STBTRUETYPEFONT=ON ^ -DMAGNUM_WITH_STBTRUETYPEFONT=ON ^
-G Ninja || exit /b -G Ninja || exit /b
cmake --build . || exit /b cmake --build . || exit /b

1
package/ci/appveyor-desktop.bat

@ -96,6 +96,7 @@ cmake .. ^
-DMAGNUM_WITH_STANFORDSCENECONVERTER=ON ^ -DMAGNUM_WITH_STANFORDSCENECONVERTER=ON ^
-DMAGNUM_WITH_STBIMAGECONVERTER=ON ^ -DMAGNUM_WITH_STBIMAGECONVERTER=ON ^
-DMAGNUM_WITH_STBIMAGEIMPORTER=ON ^ -DMAGNUM_WITH_STBIMAGEIMPORTER=ON ^
-DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON ^
-DMAGNUM_WITH_STBTRUETYPEFONT=ON ^ -DMAGNUM_WITH_STBTRUETYPEFONT=ON ^
%COMPILER_EXTRA% -G Ninja || exit /b %COMPILER_EXTRA% -G Ninja || exit /b
cmake --build . || exit /b cmake --build . || exit /b

1
package/ci/unix-desktop-gles.sh

@ -73,6 +73,7 @@ cmake .. \
-DMAGNUM_WITH_STANFORDSCENECONVERTER=ON \ -DMAGNUM_WITH_STANFORDSCENECONVERTER=ON \
-DMAGNUM_WITH_STBIMAGECONVERTER=ON \ -DMAGNUM_WITH_STBIMAGECONVERTER=ON \
-DMAGNUM_WITH_STBIMAGEIMPORTER=ON \ -DMAGNUM_WITH_STBIMAGEIMPORTER=ON \
-DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON \
-DMAGNUM_WITH_STBTRUETYPEFONT=ON \ -DMAGNUM_WITH_STBTRUETYPEFONT=ON \
-G Ninja -G Ninja
ninja install ninja install

1
package/ci/unix-desktop.sh

@ -77,6 +77,7 @@ cmake .. \
-DMAGNUM_WITH_STANFORDSCENECONVERTER=ON \ -DMAGNUM_WITH_STANFORDSCENECONVERTER=ON \
-DMAGNUM_WITH_STBIMAGECONVERTER=ON \ -DMAGNUM_WITH_STBIMAGECONVERTER=ON \
-DMAGNUM_WITH_STBIMAGEIMPORTER=ON \ -DMAGNUM_WITH_STBIMAGEIMPORTER=ON \
-DMAGNUM_WITH_STBRESIZEIMAGECONVERTER=ON \
-DMAGNUM_WITH_STBTRUETYPEFONT=ON \ -DMAGNUM_WITH_STBTRUETYPEFONT=ON \
-G Ninja -G Ninja
ninja install ninja install

28
src/python/magnum/test/test_trade.py

@ -1645,10 +1645,36 @@ class ImageConverter(unittest.TestCase):
converter.flags = trade.ImageConverterFlags.VERBOSE converter.flags = trade.ImageConverterFlags.VERBOSE
self.assertEqual(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): def test_image2d(self):
importer = trade.ImporterManager().load_and_instantiate('StbImageImporter') importer = trade.ImporterManager().load_and_instantiate('StbImageImporter')
importer.open_file(os.path.join(os.path.dirname(__file__), 'rgb.png')) importer.open_file(os.path.join(os.path.dirname(__file__), 'rgb.png'))
image = importer.image2d(0) 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') 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")) converter.convert_to_file(image, os.path.join(tmp, "image.png"))
self.assertTrue(os.path.exists(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 = trade.ImporterManager().load_and_instantiate('StbImageImporter')
importer.open_file(os.path.join(os.path.dirname(__file__), 'rgb.png')) importer.open_file(os.path.join(os.path.dirname(__file__), 'rgb.png'))
image = importer.image2d(0) image = importer.image2d(0)

14
src/python/magnum/trade.cpp

@ -447,6 +447,17 @@ template<class R, Containers::Optional<R>(Trade::AbstractImporter::*f)(UnsignedI
/* Can't be named just checkResult() because the AbstractSceneConverter /* Can't be named just checkResult() because the AbstractSceneConverter
overload would confuse GCC 4.8 */ overload would confuse GCC 4.8 */
template<class R, class T, Containers::Optional<R>(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<R> 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 */ /** @todo drop std::string in favor of our own string caster */
template<class T, bool(Trade::AbstractImageConverter::*f)(const T&, Containers::StringView)> void checkImageConverterResult(Trade::AbstractImageConverter& self, const T& image, const std::string& filename) { template<class T, bool(Trade::AbstractImageConverter::*f)(const T&, Containers::StringView)> 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 /** @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) { }, [](Trade::AbstractImageConverter& self, Trade::ImageConverterFlag flags) {
self.setFlags(flags); self.setFlags(flags);
}, "Converter flags") }, "Converter flags")
.def("convert", checkImageConverterResult<Trade::ImageData1D, ImageView1D, &Trade::AbstractImageConverter::convert>, "Convert a 1D image", py::arg("image"))
.def("convert", checkImageConverterResult<Trade::ImageData2D, ImageView2D, &Trade::AbstractImageConverter::convert>, "Convert a 2D image", py::arg("image"))
.def("convert", checkImageConverterResult<Trade::ImageData3D, ImageView3D, &Trade::AbstractImageConverter::convert>, "Convert a 3D image", py::arg("image"))
.def("convert_to_file", checkImageConverterResult<ImageView1D, &Trade::AbstractImageConverter::convertToFile>, "Convert a 1D image to a file", py::arg("image"), py::arg("filename")) .def("convert_to_file", checkImageConverterResult<ImageView1D, &Trade::AbstractImageConverter::convertToFile>, "Convert a 1D image to a file", py::arg("image"), py::arg("filename"))
.def("convert_to_file", checkImageConverterResult<ImageView2D, &Trade::AbstractImageConverter::convertToFile>, "Convert a 2D image to a file", py::arg("image"), py::arg("filename")) .def("convert_to_file", checkImageConverterResult<ImageView2D, &Trade::AbstractImageConverter::convertToFile>, "Convert a 2D image to a file", py::arg("image"), py::arg("filename"))
.def("convert_to_file", checkImageConverterResult<ImageView3D, &Trade::AbstractImageConverter::convertToFile>, "Convert a 3D image to a file", py::arg("image"), py::arg("filename")); .def("convert_to_file", checkImageConverterResult<ImageView3D, &Trade::AbstractImageConverter::convertToFile>, "Convert a 3D image to a file", py::arg("image"), py::arg("filename"));

Loading…
Cancel
Save