C#开发训练营

第26课:图形图像(4)

本课将讨论图片的水平和垂直翻转,特定角度和任意角度的旋转、保存图片,以及卡片制作示例和二维码的生成等内容。

旋转与翻转

Bitmap类中的RotateFilp()方法可以进行位图的垂直和水平翻转,以及特定角度的旋转;方法需要一个参数,定义为RotateFlipType枚举类型,枚举值定义了旋转或翻转的方式,如:

  • RotateNoneFlipNone,不进行旋转和翻转操作。
  • Rotate90FlipNone,顺时针90度旋转。
  • Rotate180FlipNone,顺时针旋转180度。
  • Rotate270FlipNone,,顺时针旋转270度。
  • RotateNoneFlipX,水平翻转。
  • Rotate90FlipX,顺时针旋转90度并进行水平翻转。
  • Rotate180FlipX,顺时针旋转180度并进行水平翻转。
  • Rotate270FlipX,顺时针旋转270度并进行水平翻转。
  • RotateNoneFlipY,垂直翻转。
  • Rotate90FlipY,顺时针旋转90度并进行垂直翻转。
  • Rotate180FlipY,顺时针旋转180度并进行垂直翻转。
  • Rotate270FlipY,顺时针旋转270度并进行垂直翻转。
  • RotateNoneFlipXY,水平翻转和垂直翻转。
  • Rotate90FlipXY,顺时针旋转90度并进行水平翻转和垂直翻转。
  • Rotate180FlipXY,顺时针旋转180度并进行水平翻转和垂直翻转。
  • Rotate270FlipXY,顺时针旋转270度并进行水平翻转和垂直翻转。

因为旋转和翻转并不涉及额外的尺寸计算,在tImage类中可以使用同名方法对RotateFlip()方法进行包装,如下面的代码。

C#
public void RotateFlip(RotateFlipType type)
{
    myBmp.RotateFlip(type);
}

使用RotateFlip()方法只能进行90、180和270度的旋转操作,那么,对于其它角度的旋转应该如何操作呢?下面就来解决这个问题。

旋转任意角度

旋转操作中的计算基于下图中的模型,其中有两个三角形需要注意,第一个是由w、h1和w1三条边组成的三角形,另一个是由h、h2和w2三条边组成的三角形;两个三角形中的角a就是中间颜色较深的矩形顺时针旋转的角度,图1中旋转的角度为30度(π/6)。

图1

旋转操作中,图中间较深颜色的矩形是原始图形的矩形,原始尺寸的宽度为w,高度为h。计算过程中需要使用正弦函数和余弦函数,所以,处理的角度大于0度并小于90度。以图中角a为例,已知原图像的宽度w,而w1为锐角a的邻边,根据余弦定理可以计算出w1=cos(a)*w,h1为锐角a的对边,根据正弦定理可以计算出h1=sin(a)*w;相同的方法可以计算出h2和w2的值;最终,在图1的模型中,原矩形顺时针旋转a度(0<a<90)后,外接矩形的宽度就是w1+w2,高度为h1+h2。

如果顺时针旋转大于90度应该怎么操作呢?我们知道,在Bitmap对象中,可以使用RotateFlip(RotateFlipType.Rotate90FlipNone)方法旋转90度,对于大于90度的旋转,可以先旋转若干个90度,最后剩余的角度就是一个锐角,可以按图1中的模型进行计算。

另一个需要注意的就是设置旋转角度为负数的情况。由于我们约定的是顺时针旋转,那么,负角度就是逆时针旋转的角度,此时,可以将负角度转换为相应的正角度值,然后按上述方法进行旋转操作。

下面的代码定义了RotateRadian()方法,其参数为顺时针旋转的角度(使用弧度值)。