Dear list,
I was just trying to shear an image to be plotted with
matplotlib (to get some snazzy 3D effect) and realized
that it's apparently not possible. Investigating further,
I realized that the underlying agg library indeed supports
shearing, as it simply uses an affine matrix for its
transforms (very much like the rest of matplotlib),
but it does not export that feature to matplotlib.
So, I just quickly added some code to actually
access the transformation matrix in the C++ code,
so that one can use it from within python. The next
step would be to hook that up to the usual code used
in matplotlib.
A patch is attached at the end of this post.
Greetings
Martin
--------------- patch follows -----------------------
commit b7d0d23d90460ee790f1e94f387070a69be661c8
Author: Martin Teichmann <martin@...977...(none)>
Make affine transformations work for images
The current code only supports scaling and maybe rotation of
images, but not all affine transformations, although it is
already prepared to do so.
This patch adds a method set_matrix to the C++ image handling code,
so that one can set (and thus perform) arbitrary affine transformations.
It also fixes a little bug which introduced weird side effects
if images were resized more than once.
diff --git a/src/_image.cpp b/src/_image.cpp
index 3278b6c..7d40664 100644
--- a/src/_image.cpp
+++ b/src/_image.cpp
@@ -92,7 +92,6 @@ Image::apply_rotation(const Py::Tuple& args)
agg::trans_affine M = agg::trans_affine_rotation(r * agg::pi / 180.0);
srcMatrix *= M;
- imageMatrix *= M;
return Py::Object();
}
@@ -156,7 +155,6 @@ Image::apply_scaling(const Py::Tuple& args)
//printf("applying scaling %1.2f, %1.2f\n", sx, sy);
agg::trans_affine M = agg::trans_affine_scaling(sx, sy);
srcMatrix *= M;
- imageMatrix *= M;
return Py::Object();
}
@@ -179,7 +177,6 @@ Image::apply_translation(const Py::Tuple& args)
//printf("applying translation %1.2f, %1.2f\n", tx, ty);
agg::trans_affine M = agg::trans_affine_translation(tx, ty);
srcMatrix *= M;
- imageMatrix *= M;
return Py::Object();
}
@@ -285,7 +282,6 @@ Image::reset_matrix(const Py::Tuple& args)
args.verify_length(0);
srcMatrix.reset();
- imageMatrix.reset();
return Py::Object();
}
@@ -316,6 +312,31 @@ Image::get_matrix(const Py::Tuple& args)
return ret;
}
+char Image::set_matrix__doc__[] =
+ "set_matrix(m11,m21,m12,m22,m13,m23)\n"
+ "\n"
+ "Set the affine transformation matrix\n"
+ " /m11,m12,m13\\\n"
+ " /m21,m22,m23|\n"
+ " \\ 0 , 0 , 1 /"
+ ;
···
Date: Wed Jul 6 14:04:44 2011 +0200
+
+Py::Object
+Image::set_matrix(const Py::Tuple& args)
+{
+ _VERBOSE("Image::set_matrix");
+
+ args.verify_length(6);
+
+ double m[6];
+ for (int i = 0;i < 6;i++)
+ {
+ m[i] = Py::Float(args[i]);
+ }
+ srcMatrix.load_from(m);
+ return Py::Object();
+}
+
char Image::resize__doc__[] =
"resize(width, height, norm=1, radius=4.0)\n"
"\n"
@@ -376,8 +397,7 @@ Image::resize(const Py::Tuple& args, const Py::Dict& kwargs)
ras.clip_box(0, 0, numcols, numrows);
- //srcMatrix *= resizingMatrix;
- //imageMatrix *= resizingMatrix;
+ imageMatrix = srcMatrix;
imageMatrix.invert();
interpolator_type interpolator(imageMatrix);
@@ -733,6 +753,7 @@ Image::init_type()
add_varargs_method("get_size_out", &Image::get_size_out,
Image::get_size_out__doc__);
add_varargs_method("reset_matrix", &Image::reset_matrix,
Image::reset_matrix__doc__);
add_varargs_method("get_matrix", &Image::get_matrix,
Image::get_matrix__doc__);
+ add_varargs_method("set_matrix", &Image::set_matrix,
Image::set_matrix__doc__);
add_keyword_method("resize", &Image::resize, Image::resize__doc__);
add_varargs_method("set_interpolation",
&Image::set_interpolation, Image::set_interpolation__doc__);
add_varargs_method("set_resample", &Image::set_resample,
Image::set_resample__doc__);
diff --git a/src/_image.h b/src/_image.h
index 8a3be54..89a923c 100644
--- a/src/_image.h
+++ b/src/_image.h
@@ -34,6 +34,7 @@ public:
Py::Object buffer_rgba(const Py::Tuple& args);
Py::Object reset_matrix(const Py::Tuple& args);
Py::Object get_matrix(const Py::Tuple& args);
+ Py::Object set_matrix(const Py::Tuple& args);
Py::Object resize(const Py::Tuple& args, const Py::Dict& kwargs);
Py::Object get_aspect(const Py::Tuple& args);
Py::Object get_size(const Py::Tuple& args);
@@ -105,6 +106,7 @@ private:
static char buffer_rgba__doc__[];
static char reset_matrix__doc__[];
static char get_matrix__doc__[];
+ static char set_matrix__doc__[];
static char resize__doc__[];
static char get_aspect__doc__[];
static char get_size__doc__[];