Geometrical raster transformations such as scaling, rotating, skewing, and perspective distortion are linear transformations, which are well-known from linear algebra. Graphics Mill allows performing projective transformations and affine transformations (a special case in projective transformations). This topic provides general information about linear transformations, highlights differences between projective and affine transformations, and describes how to apply these transformations using Graphics Mill.
In mathematics, a linear transformation is a function that maps one vector space into another. Such transformations are often implemented by a matrix. A transformation is considered to be linear if it preserves vector addition and scalar multiplication. A projective transformation shows how the perceived objects change as the observer's viewpoint changes. These transformations allow the creating of perspective distortion. Affine transformations are used for scaling, skewing and rotation. Graphics Mill supports both these classes of transformations.
Both, affine and projective transformations, can be represented by the following matrix:
,
where:
is a rotation matrix. This matrix defines the type of the transformation that will be performed: scaling, rotation, and so on.
is the translation vector, which specifies movement.
is the projection vector. For affine transformations all elements of this vector are equal to 0.
Geometrical raster transformations are applied to vectors containing coordinates of a point, the x and y values of a pixel. To apply a transformation it is necessary to multiply this vector by a matrix representing the transformation:
The result of this multiplication is a vector having transformed coordinates, x' and y' in the figure above.
The sole difference between these affine and projective transformations is in the last line of the transformation matrix. For affine transformations, the first two elements of this line are zeros. This leads to the following differences in operations properties:
A projective transformation can be represented as the transformation of an arbitrary quadrangle (that is a system of four points) into another one. Affine transformation is the transformation of a triangle. The image below illustrates this:
If a transformation matrix represents a non-convex quadrangle (such matrices are called singular), then the transformation cannot be performed through matrix multiplication. A quadrangle is non-convex if one of the following is true:
The image below demonstrates non-convex quadrangles:
Make sure that your transformation matrix is not singular. Graphics Mill is not able to apply such transformations.
Generally, if you want to apply a linear transformation, you have to calculate the transformation matrix. Fortunately, Graphics Mill can do all the math for you. To apply a projective transformation in Graphics Mill perform the following steps:
When choosing destination points remember that the transformation matrix should be non-singular. Do not specify points that form a non-convex quadrangle.
The following code applies the perspective distortion effect to a source image:
using (var bitmap = new Bitmap(@"Images\in.jpg")) { System.Drawing.PointF[] source = { new System.Drawing.PointF(0f, 0f), new System.Drawing.PointF(0f, bitmap.Height), new System.Drawing.PointF(bitmap.Width, bitmap.Height), new System.Drawing.PointF(bitmap.Width, 0f) }; System.Drawing.PointF[] target = { new System.Drawing.PointF(0f, 0f), new System.Drawing.PointF(0f, bitmap.Height), new System.Drawing.PointF(bitmap.Width * 0.75f, bitmap.Height - 50f), new System.Drawing.PointF(bitmap.Width * 0.75f, 80f) }; var matrix = Matrix.CreateFromProjectivePoints(source, target); using (var transform = new MatrixTransform(matrix)) { using (var result = transform.Apply(bitmap)) { result.Save(@"Images\Output\out.jpg"); } } }
Suppose you have the following source image:
Here is the image that will be produced by the code above:
Affine transformations are a special case when using projective transformations: to set an affine transformation you should specify triangles. To apply an affine transformation in Graphics Mill you should perform almost the same steps as for a projective one:
The code below skews a source image and saves the result:
using (var bitmap = new Bitmap(@"Images\in.jpg")) { System.Drawing.PointF[] source = { new System.Drawing.PointF(0f, 0f), new System.Drawing.PointF(0f, 80f), new System.Drawing.PointF(80f, 0f) }; System.Drawing.PointF[] target = { new System.Drawing.PointF(20, 0f), new System.Drawing.PointF(0f, 80f), new System.Drawing.PointF(80f, 0f) }; var matrix = Matrix.CreateFromAffinePoints(source, target); using (var transform = new MatrixTransform(matrix)) { using (var result = transform.Apply(bitmap)) { result.Save(@"Images\Output\out.jpg"); } } }
Suppose you have the following source image:
Here is the image that will be produced by the code above:
For base affine transformations Graphics Mill provides the special classes:
It is recommended to use these classes.