实例介绍
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; } }
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论