[转]C#中的矩阵转换,应用.net GDI+
2011-07-26 22:54
141 查看
说明: 在.NET中,利用
System.Drawing.Drawing2D命名空间下的Matrix类,可以使对二维图像坐标转换的处理大大简化,在这篇文章中,我将向读者分享如何利用Matrix类进行二维图像的坐标转换。 背景知识:
Matrix类中描述了3行2列的六个项,举个例子,对
Matrix使用默认的构造方法进行构造时,默认构造方法的参数为( 1,0,0,1,0,0 ),矩阵描述如下
这是下面这个矩阵的简化
最后一列始终为
因此,一个X轴方向移动3,Y轴方向移动2的的平移变换可以被表示成如下形式:
但实际上内部的表示为
需要说明一点,变换矩阵是对图像矢量做右乘.举一个例子,我们现在有这样一个图形,包含4个点:(1,1) ( 2,3) (5,0) (6 7),这个图形向量可以被表示成一个4行2列的矩阵:
但实际上内部的表示为
当我们将变换矩阵应用到这个图像矩阵时,变换矩阵是对图像矩阵的右乘
结果矩阵的最后一列是被忽略的,因此变换结果为四个新点(4,3) (5,5) (8,2) (9,9) 一个复合变换由两个以上的矩阵组成,我们看一个例子,一个X轴分量为2,Y轴分量为3的缩放矩阵如下图所示:
但实际上内部的表示为
当我们进行一个先平移再缩放的复合变换时,缩放矩阵应该右乘平移矩阵,
同样,如果我们进行一个先缩放再平移的坐标变换时平移矩阵应该右乘缩放矩阵. 右乘也叫做追加矩阵,左乘叫做前置矩阵,左边的矩阵总是先被应用的. 矩阵转换: 这篇文章中,只针对以下四种变换: (1)旋转 (2)平移 (3)缩放 (4)翻转 如何实例化一个Matrix类:
//这会创建一个单位矩阵(1,0,0,1,0,0) Matrix m=new Matrix();
也可以在实例化时设置初始值
//这会创建一个矩阵(1,2,3,4,5,6) Matrix m=new Matrix(1,2,3,4,5,6);
Matrix类实现了多种方法
Rotate
Translate
Scale
Multiply
要创建一个复合矩阵,先要创建一个单位矩阵,然后用以上的方法来追加或者前置(append/prepend)变换
Matrix m=new Matrix(); //从初始点移动至200,200 m.Translate(200,200); //顺时针旋转90度 m.Rotate(90,MatrixOrder.Prepend);
在上面的代码中,因为旋转矩阵是前置矩阵,所以旋转操作会首先被应用
在矩阵变换中,变换的先后顺序是非常重要的,先平移后旋转还是先旋转后平移,结果会有很大不同(旋转时根据原点的).如下图所示
应用Matrix对象
下面的三个GDI+对象应用了Matrix对象
Graphics
Pen
GraphicsPath
以上每个对象都包含了Transform属性,这个属性是Matrix类型的,默认的Transform属性是一个单位矩阵,所有的绘制操作都会遵循各自的Transform属性
因此举个简单的例子,如果将顺时针旋转45度的变换矩阵赋给了Graphics对象的Transform属性,然后画一条水平线,这条线会被呈现为倾斜45度.
矩阵变换应用在GraphicsPath对象上时特别有意思,当Transform属性属性被赋值时,GraphicsPath对象中的PathPoints会立即被更改以反映此次变换.
利用这一行为我们可以在
GraphicsPath对象上进行变换,并用DrawImage方法来呈现这次变换
Graphics g=Graphics.FromImage(pictureBox1.Image); //.. GraphicsPath gp=new GraphicsPath(); Image imgpic=(Image)pictureBoxBase.Image.Clone(); //多边形的坐标必须为 //point 1 = 左上角 //point 2 = 右上角 //point 3 = 右下角 if(cbFlipY.CheckState ==CheckState.Checked) gp.AddPolygon(new Point[]{new Point(0,imgpic.Height), new Point(imgpic.Width,imgpic.Height), new Point(0,0)}); else gp.AddPolygon(new Point[]{new Point(0,0), new Point(imgpic.Width,0), new Point(0,imgpic.Height)}); //apply the transformation matrix on the graphical path gp.Transform(mm1); //get the resulting path points PointF[] pts=gp.PathPoints; //draw on the picturebox content of imgpic using the local transformation //using the resulting parralleogram described by pts g.DrawImage(imgpic,pts);
翻转:
很遗憾,Matrix类型中没有关于翻转的方法,但是翻转矩阵大家都知道,对于沿X轴翻转,矩阵为(1,0,0,-1,0,0),沿Y轴旋转,矩阵为
(-1,0,0,1,0,0)
仿射变换:
矩阵变换不仅是简单的点到点的变换
举个例子,有一个矩形,顶点为(0,0) (0,1) (1,1) (1,0),如果单位是像素,那么组成这个矩阵的就是这四个点,如果我们对这个矩阵进行X轴Y轴分量都为2,相对于(0,0)进行缩放,那么结果矩形的四个顶点为(0,0) (0,2) (2,2) (2,0),它还包含四个顶点之间的其他点,为什么四个点的图形被转换成了多于四个点的图形呢?
答案就是,变换操作利用插值来产生哪些不能直接映射的点(未知像素的值使用已知像素的值来估计)
相关文章推荐
- 实现C#和VB.net之间的相互转换
- 关于C#/.NET中委托和事件的机制和应用的故事(转)
- C#.NET 中的类型转换
- [C#] Direct2D 学习笔记 (一)vb.net转换为c#
- C# Stream 和 byte[] 之间的转换(文件流的应用)
- C# .NET中的 反射的应用
- ASP.NET:C#中时间格式的转换
- n个VB.Net to C# (C# to VB.net)代码转换(互换互转)工具
- 利用SharpDevelop做C#与vb.net代码转换很好
- C#.NET中的 sender Tag 功能在支持多语言的通用权限管理系统组件中的实际应用范例
- C#.NET 中的类型转换
- C#中的矩阵转换
- c#.net上传文件到数据库中(把文件转换成二进制流存在后台数据库)
- ASP.NET C# 日期时间年月日时分秒格式及转换
- 关于VB.Net C#代码转换工具
- 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换
- FCK在ASP.NET(C#)中的应用,FCK上传文件按照年月的形式保存
- 比如将一个变量转换到INT类型 C#.NET中如何进行强制类型转换
- 详解讨论如何完成C#转换为VB.NET
- C#.NET 中的类型转换