[libcamera-devel] [PATCH v7 09/13] py: add Transform

Tomi Valkeinen tomi.valkeinen at ideasonboard.com
Thu May 5 12:41:00 CEST 2022


Add binding for Transform.

C++'s Transform is an enum class, but we expose it as a Python class so
that it can be easily manipulated.

Original version from David Plowman <david.plowman at raspberrypi.com>.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 src/py/libcamera/pymain.cpp | 63 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp
index db9d90ab..3d2393ab 100644
--- a/src/py/libcamera/pymain.cpp
+++ b/src/py/libcamera/pymain.cpp
@@ -152,6 +152,7 @@ PYBIND11_MODULE(_libcamera, m)
 	auto pyControlId = py::class_<ControlId>(m, "ControlId");
 	auto pyRequest = py::class_<Request>(m, "Request");
 	auto pyFrameMetadata = py::class_<FrameMetadata>(m, "FrameMetadata");
+	auto pyTransform = py::class_<Transform>(m, "Transform");
 
 	/* Global functions */
 	m.def("logSetLevel", &logSetLevel);
@@ -342,7 +343,8 @@ PYBIND11_MODULE(_libcamera, m)
 		.def("validate", &CameraConfiguration::validate)
 		.def("at", py::overload_cast<unsigned int>(&CameraConfiguration::at), py::return_value_policy::reference_internal)
 		.def_property_readonly("size", &CameraConfiguration::size)
-		.def_property_readonly("empty", &CameraConfiguration::empty);
+		.def_property_readonly("empty", &CameraConfiguration::empty)
+		.def_readwrite("transform", &CameraConfiguration::transform);
 
 	pyStreamConfiguration
 		.def("toString", &StreamConfiguration::toString)
@@ -462,4 +464,63 @@ PYBIND11_MODULE(_libcamera, m)
 			transform(self.planes().begin(), self.planes().end(), v.begin(), [](const auto &p) { return p.bytesused; });
 			return v;
 		});
+
+	pyTransform
+		.def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) {
+			bool ok;
+
+			Transform t = transformFromRotation(rotation, &ok);
+			if (!ok)
+				throw std::runtime_error("Unable to create the transform");
+
+			if (hflip)
+				t ^= Transform::HFlip;
+			if (vflip)
+				t ^= Transform::VFlip;
+			if (transpose)
+				t ^= Transform::Transpose;
+			return t;
+		}), py::arg("rotation") = 0, py::arg("hflip") = false,
+		    py::arg("vflip") = false, py::arg("transpose") = false)
+		.def(py::init([](Transform &other) { return other; }))
+		.def("__repr__", [](Transform &self) {
+			return "<libcamera.Transform '" + std::string(transformToString(self)) + "'>";
+		})
+		.def_property("hflip",
+			      [](Transform &self) {
+				      return !!(self & Transform::HFlip);
+			      },
+			      [](Transform &self, bool hflip) {
+				      if (hflip)
+					      self |= Transform::HFlip;
+				      else
+					      self &= ~Transform::HFlip;
+			      })
+		.def_property("vflip",
+			      [](Transform &self) {
+				      return !!(self & Transform::VFlip);
+			      },
+			      [](Transform &self, bool vflip) {
+				      if (vflip)
+					      self |= Transform::VFlip;
+				      else
+					      self &= ~Transform::VFlip;
+			      })
+		.def_property("transpose",
+			      [](Transform &self) {
+				      return !!(self & Transform::Transpose);
+			      },
+			      [](Transform &self, bool transpose) {
+				      if (transpose)
+					      self |= Transform::Transpose;
+				      else
+					      self &= ~Transform::Transpose;
+			      })
+		.def("inverse", [](Transform &self) { return -self; })
+		.def("invert", [](Transform &self) {
+			self = -self;
+		})
+		.def("compose", [](Transform &self, Transform &other) {
+			self = self * other;
+		});
 }
-- 
2.34.1



More information about the libcamera-devel mailing list