C#提供3点变形图像功能,在实际运用中有很大局限,本例介绍4点变形背景透明图像的方式。按照左上、右上、左下、右下四个坐标位置对背景透明图像进行变形处理,本例按照立方体横向、纵向180度,对图像进行变形,并判断正反面显示不同图像,
图像可以是任意的png图像,也可设置背景透明的异形图像来进行显示,2副一样大小就可以了。
处理180帧图像,经测需1500毫秒左右。 
  
  
 
 /// <summary>  /// 在项目属性 “生成”中选择“优化代码”  /// </summary>  public partial class Form1 : Form  {    private Cube cube; //三维立方体    private Point[,] corners = new Point[180, 4]; //四点坐标    private FreeTransform[] filters = new FreeTransform[180]; //图像过滤    private PointF[] set = new PointF[180]; //图像坐标点    private Bitmap[] display = new Bitmap[180]; //变形后图像存放    Bitmap _firstBmp, _secondBmp; //原始图像,正面、反面    int _width, _height, _type=0, _speed = 3; //图像 宽度、高度、横向或纵向(0、1)、连续显示速度    int _transparent = 230; //图像透明度    private Point origin; //显示图像的坐标位置    Thread[] rtd = new Thread[180]; //变形处理图像线程    AlphaForm putForm = new AlphaForm(); //alpha通道的显示图像窗体    int _order = 0; //正、反面,能被2整除为正面    public Form1()    {      InitializeComponent();      _firstBmp = Image.FromFile("1.png") as Bitmap; //取得正面图像      _secondBmp = Image.FromFile("2.png") as Bitmap; //取得反面图像      label4.Text = "图像信息:宽度 -- "  _firstBmp.Width  ",高度 -- "  _firstBmp.Height;      origin = new Point(400,400); //图像显示坐标      _width = _firstBmp.Width; //宽度      _height = _firstBmp.Height; //高度      button2.Enabled = false; //显示图像按钮不可用      putForm = new AlphaForm(); //alpha窗体    }    /// <summary>    /// 计算图像变形4点坐标,以及显示坐标位置    /// </summary>    public void initCub()    {      cube = new Cube(_width, _height, 1); //建立三维立方体,x为宽,y为高,z深度为1,即只显示正反2面      for (int i = 0; i < 180; i )      {        if (_type == 0) cube.RotateY = i; //横向        if (_type == 1) cube.RotateX = i; //纵向        cube.calcCube(origin); //计算坐标点        corners[i, 0] = cube.d; //左上        corners[i, 1] = cube.a; //右上        corners[i, 2] = cube.c; //左下        corners[i, 3] = cube.b; //右下        filters[i] = new FreeTransform(); //建立图像区域        //总共180帧图像,90帧正面图像,其余反面图像        if (i < 90) filters[i].Bitmap = _firstBmp; //如为正面,装入正面图像,        else filters[i].Bitmap = _secondBmp; //装入反面图像        if (_type == 0) //横向        {          rtd[i] = new Thread(get_imgHs); //建立线程          int t = 0;          //判断坐标位置是否切换到正反面,进行坐标转换          if ((corners[i, 0].X - corners[i, 1].X) <= 1) //正面          {            //4点坐标            if (corners[i, 0].Y < corners[i, 1].Y) t = corners[i, 0].Y;            else t = corners[i, 1].Y;            //显示坐标            set[i] = new PointF(corners[i, 0].X  _width / 2, t  _height / 2);           }          else //反面          {            //4点坐标            if (corners[i, 1].Y < corners[i, 0].Y) t = corners[i, 1].Y;            else t = corners[i, 0].Y;            //显示坐标            set[i] = new PointF(corners[i, 1].X  _width / 2, t  _height / 2);           }        }        else        if (_type == 1) //纵向        {          rtd[i] = new Thread(get_imgVs); //建立线程          int t = 0;          //判断坐标位置是否切换到正反面,进行坐标转换          if ((corners[i, 0].Y - corners[i, 2].Y) <= 1) //正面          {            //4点坐标            if (corners[i, 0].Y < corners[i, 2].Y) t = corners[i, 0].Y;            else t = corners[i, 2].Y;            //显示坐标            set[i] = new PointF(corners[i, 0].X  _width / 2, t  _height / 2);          }          else          {            //4点坐标            if (corners[i, 2].Y < corners[i, 0].Y) t = corners[i, 2].Y;            else t = corners[i, 0].Y;            //显示坐标            set[i] = new PointF(corners[i, 0].X  _width / 2, t  _height / 2);          }        }        //显示到编辑框中        richTextBox1.AppendText((i 1) ". 坐标:"  cube.d  ","  cube.a  ","  cube.c  ","  cube.b "\r");      }    }    /// <summary>    /// 开始线程运算    /// </summary>    public void Initialize3dPut()    {      for (int i = 0; i < 180; i )      {        rtd[i].Start(i);      }    }    /// <summary>    /// 横向生成图像    /// </summary>    /// <param name="num"></param>    private void get_imgHs(object num)    {      updateImage_Hs((int)num);    }    /// <summary>    /// 纵向生成图像    /// </summary>    /// <param name="num"></param>    private void get_imgVs(object num)    {      updateImage_Vs((int)num);    }    /// <summary>    /// 生成横向图像    /// </summary>    /// <param name="num"></param>    private void updateImage_Hs(int num)    {      if ((corners[num, 0].X - corners[num, 1].X) <= 1) //正面      {        filters[num].VertexLeftTop = corners[num, 0]; //左上        filters[num].VertexTopRight = corners[num, 1]; //右上        filters[num].VertexBottomLeft = corners[num, 2]; //左下        filters[num].VertexRightBottom = corners[num, 3]; //右下      }      else//反面      {        filters[num].VertexLeftTop = corners[num, 1]; //左上        filters[num].VertexTopRight = corners[num, 0];//右上        filters[num].VertexBottomLeft = corners[num, 3];//左下        filters[num].VertexRightBottom = corners[num, 2];//右下      }      display[num] = filters[num].Bitmap; //装入图像    }    /// <summary>    /// 生成纵向图像    /// </summary>    /// <param name="num"></param>    private void updateImage_Vs(int num)    {      if ((corners[num, 0].Y - corners[num, 2].Y) <= 1) //正面      {        filters[num].VertexLeftTop = corners[num, 0];//左上        filters[num].VertexTopRight = corners[num, 1];//右上        filters[num].VertexBottomLeft = corners[num, 2];//左下        filters[num].VertexRightBottom = corners[num, 3];//右下      }      else //反面      {        filters[num].VertexLeftTop = corners[num, 2];//左上        filters[num].VertexTopRight = corners[num, 3];//右上        filters[num].VertexBottomLeft = corners[num, 0];//左下        filters[num].VertexRightBottom = corners[num, 1];//右下      }      display[num] = filters[num].Bitmap; //装入图像    }    /// <summary>    /// 选择横向、纵向选项,checkBox1、checkBox2的click事件都为此项    /// </summary>    private void checkBox1_Click(object sender, EventArgs e)    {      richTextBox1.Clear(); //清空编辑框      button2.Enabled = false; //显示图像按钮不可用      CheckBox ck = (CheckBox)sender;      //2个都设置为未选择      checkBox1.Checked = false;       checkBox2.Checked = false;      //当前点击的置为选中      ck.Checked = true;      //取得横向或纵向值      _type = int.Parse(ck.Tag.ToString());     }    /// <summary>    /// 初始化按钮,开始运算图像变形以及坐标    /// </summary>    private void button1_Click(object sender, System.EventArgs e)    {      label1.Text = "计算耗时...";      Application.DoEvents();      initCub(); //计算图像变形4点坐标,以及显示坐标位置      Stopwatch st = new Stopwatch(); //取得运行时间      st.Start(); //开始计时      Initialize3dPut();      st.Stop(); //计时结束      label1.Text = "180帧图像,耗时:" st.ElapsedMilliseconds.ToString() " 毫秒";      button2.Enabled = true; //可以使用显示图像按钮    }    /// <summary>    /// 强制线程sleep时间    /// </summary>    [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod")]    public static extern uint _BeginPeriod(uint uMilliseconds);    [DllImport("winmm.dll", EntryPoint = "timeEndPeriod")]    public static extern uint _EndPeriod(uint uMilliseconds);    //图像数据交换    Bitmap[] _temp = new Bitmap[180];    /// <summary>    /// 连续显示4点变形后图像    /// </summary>    private void button2_Click(object sender, EventArgs e)    {      //确定显示速度      try      {        _speed = int.Parse(textBox1.Text);      }      catch { _speed = 3; textBox1.Text = "3"; }      //判断正面、反面      if (_order % 2 == 0)      {        for (int i = 0; i < 180; i )        {          _temp[i] = display[i];        }      }      else //反面      {        for (int i = 179; i >= 0; i--)        {          _temp[179 - i] = display[i];        }      }      //显示图像窗体      putForm.Location = Point.Round(set[0]); //图像窗体位置      //窗体图像      if (_order % 2 == 0) putForm.SetBitmap(_firstBmp, (byte)_transparent);       else putForm.SetBitmap(_secondBmp, (byte)_transparent);      putForm.Show(); //显示窗体      _BeginPeriod((uint)_speed); //强制制定sleep时间开始      for (int i = 0; i < 180; i )      {        putForm.Location = Point.Ceiling(set[i]); //转换PoinF 为 Point        putForm.SetBitmap(_temp[i], (byte)_transparent); //设置图像        Thread.Sleep(_speed); //时间间隔      }      _EndPeriod((uint)_speed);//强制制定sleep时间结束      //显示最后一帧图像      putForm.Location = Point.Round(set[0]);       if (_order % 2 == 0) putForm.SetBitmap(_secondBmp,(byte) _transparent);      else putForm.SetBitmap(_firstBmp, (byte)_transparent);      //显示图像的次数      _order = 1;    }      }

 
  
					
				
评论