Browse Source

python: exposed basics of trade.AbstractImageConverter.

pull/15/head
Vladimír Vondruš 4 years ago
parent
commit
da21863ac7
  1. 28
      doc/python/magnum.trade.rst
  2. 1
      doc/python/pages/changelog.rst
  3. 1
      package/ci/appveyor-desktop-gles.bat
  4. 1
      package/ci/appveyor-desktop.bat
  5. 1
      package/ci/unix-desktop-gles.sh
  6. 1
      package/ci/unix-desktop.sh
  7. 24
      src/python/magnum/test/test_trade.py
  8. 23
      src/python/magnum/trade.cpp

28
doc/python/magnum.trade.rst

@ -166,3 +166,31 @@
:raise RuntimeError: If image import fails :raise RuntimeError: If image import fails
:raise IndexError: If :p:`id` is negative or not less than :raise IndexError: If :p:`id` is negative or not less than
:ref:`image3d_count` :ref:`image3d_count`
.. py:class:: magnum.trade.ImageConverterManager
:summary: Manager for :ref:`AbstractImageConverter` plugin instances
Each plugin returned by :ref:`instantiate()` or :ref:`load_and_instantiate()`
references its owning :ref:`ImageConverterManager` through
:ref:`AbstractImageConverter.manager`, ensuring the manager is not deleted
before the plugin instances are.
.. py:class:: magnum.trade.AbstractImageConverter
Similarly to C++, image converter plugins are loaded through
:ref:`ImageConverterManager`:
..
>>> from magnum import trade
.. code:: py
>>> manager = trade.ImageConverterManager()
>>> converter = manager.load_and_instantiate('PngImageConverter')
Unlike C++, errors in both API usage and file parsing are reported by
raising an exception. See particular function documentation for detailed
behavior.
.. py:function:: magnum.trade.AbstractImageConverter.convert_to_file
:raise RuntimeError: If image conversion fails

1
doc/python/pages/changelog.rst

@ -90,6 +90,7 @@ Changelog
:ref:`platform.glfw.Application.exit_event` :ref:`platform.glfw.Application.exit_event`
- Exposed :ref:`platform.glfw.Application.swap_interval` and - Exposed :ref:`platform.glfw.Application.swap_interval` and
:ref:`platform.glfw.Application.main_loop_iteration` :ref:`platform.glfw.Application.main_loop_iteration`
- Exposed a basic interface of :ref:`trade.AbstractImageConverter`
- Exposed :ref:`Color3.red()` and other convenience constructors (see - Exposed :ref:`Color3.red()` and other convenience constructors (see
:gh:`mosra/magnum-bindings#12`) :gh:`mosra/magnum-bindings#12`)
- Fixed issues with an in-source build (see :gh:`mosra/magnum-bindings#13`) - Fixed issues with an in-source build (see :gh:`mosra/magnum-bindings#13`)

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

@ -75,6 +75,7 @@ cmake .. ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^ -DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DBUILD_STATIC=%BUILD_STATIC% ^ -DBUILD_STATIC=%BUILD_STATIC% ^
-DWITH_DDSIMPORTER=ON ^ -DWITH_DDSIMPORTER=ON ^
-DWITH_STBIMAGECONVERTER=ON ^
-DWITH_STBIMAGEIMPORTER=ON ^ -DWITH_STBIMAGEIMPORTER=ON ^
-DWITH_CGLTFIMPORTER=ON ^ -DWITH_CGLTFIMPORTER=ON ^
-G Ninja || exit /b -G Ninja || exit /b

1
package/ci/appveyor-desktop.bat

@ -82,6 +82,7 @@ cmake .. ^
-DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^ -DCMAKE_INSTALL_PREFIX=%APPVEYOR_BUILD_FOLDER%/deps ^
-DBUILD_STATIC=%BUILD_STATIC% ^ -DBUILD_STATIC=%BUILD_STATIC% ^
-DWITH_DDSIMPORTER=ON ^ -DWITH_DDSIMPORTER=ON ^
-DWITH_STBIMAGECONVERTER=ON ^
-DWITH_STBIMAGEIMPORTER=ON ^ -DWITH_STBIMAGEIMPORTER=ON ^
-DWITH_CGLTFIMPORTER=ON ^ -DWITH_CGLTFIMPORTER=ON ^
%COMPILER_EXTRA% -G Ninja || exit /b %COMPILER_EXTRA% -G Ninja || exit /b

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

@ -58,6 +58,7 @@ cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DBUILD_STATIC=$BUILD_STATIC \ -DBUILD_STATIC=$BUILD_STATIC \
-DWITH_DDSIMPORTER=ON \ -DWITH_DDSIMPORTER=ON \
-DWITH_STBIMAGECONVERTER=ON \
-DWITH_STBIMAGEIMPORTER=ON \ -DWITH_STBIMAGEIMPORTER=ON \
-DWITH_CGLTFIMPORTER=ON \ -DWITH_CGLTFIMPORTER=ON \
-G Ninja -G Ninja

1
package/ci/unix-desktop.sh

@ -66,6 +66,7 @@ cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DBUILD_STATIC=$BUILD_STATIC \ -DBUILD_STATIC=$BUILD_STATIC \
-DWITH_DDSIMPORTER=ON \ -DWITH_DDSIMPORTER=ON \
-DWITH_STBIMAGECONVERTER=ON \
-DWITH_STBIMAGEIMPORTER=ON \ -DWITH_STBIMAGEIMPORTER=ON \
-DWITH_CGLTFIMPORTER=ON \ -DWITH_CGLTFIMPORTER=ON \
-G Ninja -G Ninja

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

@ -25,6 +25,7 @@
import os import os
import sys import sys
import tempfile
import unittest import unittest
from corrade import pluginmanager from corrade import pluginmanager
@ -265,3 +266,26 @@ class Importer(unittest.TestCase):
with self.assertRaisesRegex(RuntimeError, "import failed"): with self.assertRaisesRegex(RuntimeError, "import failed"):
importer.image2d(0) importer.image2d(0)
class ImageConverter(unittest.TestCase):
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)
converter = trade.ImageConverterManager().load_and_instantiate('StbImageConverter')
with tempfile.TemporaryDirectory() as tmp:
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):
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')
with tempfile.TemporaryDirectory() as tmp:
with self.assertRaisesRegex(RuntimeError, "conversion failed"):
converter.convert_to_file(image, os.path.join(tmp, "image.hdr"))

23
src/python/magnum/trade.cpp

@ -29,6 +29,7 @@
#include <Corrade/Containers/StringStl.h> /** @todo drop once we have our string casters */ #include <Corrade/Containers/StringStl.h> /** @todo drop once we have our string casters */
#include <Magnum/ImageView.h> #include <Magnum/ImageView.h>
#include <Magnum/Trade/AbstractImporter.h> #include <Magnum/Trade/AbstractImporter.h>
#include <Magnum/Trade/AbstractImageConverter.h>
#include <Magnum/Trade/ImageData.h> #include <Magnum/Trade/ImageData.h>
#include <Magnum/Trade/MeshData.h> #include <Magnum/Trade/MeshData.h>
@ -241,6 +242,17 @@ template<class R, Containers::Optional<R>(Trade::AbstractImporter::*f)(UnsignedI
return *std::move(out); return *std::move(out);
} }
/** @todo drop std::string in favor of our own string caster */
template<class T, bool(Trade::AbstractImageConverter::*f)(const T&, Containers::StringView)> void checkResult(Trade::AbstractImageConverter& self, const T& image, const std::string& filename) {
/** @todo log redirection -- but we'd need assertions to not be part of
that so when it dies, the user can still see why */
bool out = (self.*f)(image, filename);
if(!out) {
PyErr_SetString(PyExc_RuntimeError, "conversion failed");
throw py::error_already_set{};
}
}
} }
void trade(py::module_& m) { void trade(py::module_& m) {
@ -318,6 +330,17 @@ void trade(py::module_& m) {
py::class_<PluginManager::Manager<Trade::AbstractImporter>, PluginManager::AbstractManager> importerManager{m, "ImporterManager", "Manager for importer plugins"}; py::class_<PluginManager::Manager<Trade::AbstractImporter>, PluginManager::AbstractManager> importerManager{m, "ImporterManager", "Manager for importer plugins"};
corrade::manager(importerManager); corrade::manager(importerManager);
/* Image converter */
py::class_<Trade::AbstractImageConverter, PluginManager::PyPluginHolder<Trade::AbstractImageConverter>> abstractImageConverter{m, "AbstractImageConverter", "Interface for image converter plugins"};
abstractImageConverter
.def("convert_to_file", checkResult<ImageView1D, &Trade::AbstractImageConverter::convertToFile>, "Convert a 1D image to a file", py::arg("image"), py::arg("filename"))
.def("convert_to_file", checkResult<ImageView2D, &Trade::AbstractImageConverter::convertToFile>, "Convert a 2D image to a file", py::arg("image"), py::arg("filename"))
.def("convert_to_file", checkResult<ImageView3D, &Trade::AbstractImageConverter::convertToFile>, "Convert a 3D image to a file", py::arg("image"), py::arg("filename"));
corrade::plugin(abstractImageConverter);
py::class_<PluginManager::Manager<Trade::AbstractImageConverter>, PluginManager::AbstractManager> imageConverterManager{m, "ImageConverterManager", "Manager for image converter plugins"};
corrade::manager(imageConverterManager);
} }
} }

Loading…
Cancel
Save