1 / 57

第 10 章 动画和图像动态显示

第 10 章 动画和图像动态显示. 【 学习内容与要点 】 本章介绍图像动画及图像动态显示的程序设计技术和技巧。重点掌握:  图像动画设计技术  图像的动态显示技术. 10.1 动画设计. 将屏幕上显示的画面或者画面的一部分,能按照一定的规则或要求在屏幕上移动的技术,称为动画技术。在屏幕上实现动画有三种方式: ( 1 ) 位置不动,形态变化。 ( 2 ) 形态不变,位置变化。 ( 3 ) 位置和形态均变化。

kiral
Download Presentation

第 10 章 动画和图像动态显示

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第10章 动画和图像动态显示 【学习内容与要点】 本章介绍图像动画及图像动态显示的程序设计技术和技巧。重点掌握: 图像动画设计技术 图像的动态显示技术

  2. 10.1 动画设计 • 将屏幕上显示的画面或者画面的一部分,能按照一定的规则或要求在屏幕上移动的技术,称为动画技术。在屏幕上实现动画有三种方式: • (1) 位置不动,形态变化。 • (2) 形态不变,位置变化。 • (3) 位置和形态均变化。 • 动画制作有许多方法, 这里使用图片对象数组,把一系列动作连续的图像保存在内存中来实现图像的快速变换。这样做有许多好处, 不必用包含多个图形框或图像控件的窗体。

  3. 10.1.1位置不动、形态变化的动画 • [例10-1] 位置不动、形态变化的动画 • 1.界面设计 • 项目界面设计如图10-1所示。在窗体上设置5个图片框PictureBox1~5,利用PictureBox的Image属性在PictureBox2~5中各输入一幅不同形态的小熊猫的图像。另外,在窗体上设置一个Button按钮和一个Timer控件。

  4. 图10-1 项目界面设计

  5. 上述设置完毕后,用鼠标缩小窗体,隐藏PictuerBox2~PictuerBox5,如图10-2所示。上述设置完毕后,用鼠标缩小窗体,隐藏PictuerBox2~PictuerBox5,如图10-2所示。

  6. 2.程序设计 • 程序设计如下: • int num; array< Bitmap^>^box; private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { • Bitmap^box2 =gcnew Bitmap(pictureBox2->Image ); • Bitmap^box3 =gcnew Bitmap(pictureBox3->Image ); • Bitmap^box4 =gcnew Bitmap(pictureBox4->Image ); • Bitmap^box5 =gcnew Bitmap(pictureBox5->Image ); • box[1]=box2; box[2]=box3;box[3]=box4;box[4]=box5; • this->timer1->Enabled=true; • this->pictureBox1->Image=box[2]; • }

  7. private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) { • if (num< 5) • { • this->pictureBox1->Image=box[num]; • num=num+1;} • else • num=1; • }

  8. 程序运行后,单击“动画”按钮,可以看到一个小熊猫在运动,如图10-3所示。程序运行后,单击“动画”按钮,可以看到一个小熊猫在运动,如图10-3所示。

  9. 10.1.2位置和形态变化的动画 • [例10-2] 位置和形态变化的动画 • 界面设计 • 界面设计如图10-4所示。在窗体上设置7个图片框PictureBox17,利用PictureBox的Image属性在PictureBox1PictureBox7中各输入一幅不同形态的图像。在窗体中加入一个timer控件。

  10. 程序设计 • 程序代码如下 • int num; • array< Bitmap^>^box; • private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { • Bitmap box1 =new Bitmap(pictureBox1.Image ); • Bitmap box2 =new Bitmap(pictureBox2.Image ); • Bitmap box3 =new Bitmap(pictureBox3.Image ); • Bitmap box4 =new Bitmap(pictureBox4.Image ); • Bitmap box5=new Bitmap(pictureBox5.Image ); • Bitmap box6 =nw Bitmap(pictureBox6.Image ); • Bitmape box7 =new Bitmap(pictureBox7.Image ); • box[0]=box1; box[1]=box2; box[2]=box3; box[3]=box4; • box[4]=box5; box[5]=box6; box[6]=box7; • timer1.Enabled=true; • }

  11. private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) { • if (num< 7) • { • pictureBox1->Image=box[num]; • num=num+1;} • else • num=0; • if (pictureBox1->Left<-100 ) • pictureBox1->Left=500; • else • pictureBox1->Left=pictureBox1->Left -10; • } • private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { • box= gcnew array<Bitmap^>(7); • }

  12. 运行结果 • 程序运行后,可以看到一个骏马在循环运动。改变Timer控件的interval属性值的大小,运动速度随值的改变而变化。如图10-5所示。

  13. 10.1.3 形态不变、位置变化的动画 • 【例10-3】建立一个形态不变、位置变化的动画项目。 • 界面设计如下。 • (1)将Timer控件加入到项目界面。 • (2)在窗体上加入一个PictureBox控件并用其Image属性加在一幅GIF图像。如图10-6所示。

  14. Point p; • private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) { • if( p.X > this->Location.X + 100) • { p.X = 0;} • if (p.Y > this->Location.Y + 100) { • p.Y = 0; • } • p.X = p.X + 6; • p.Y = p.Y + 10; • this->pictureBox1->Location = p; • } • }; • }

  15. 小鸟飞翔

  16. 10.1.4 图形动画 • [例10-4] 小球运动 • 界面设计如图10-8所示。

  17. private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { • int i; • double pi,g; • double x,y,x1,y1; • pi=3.1415926; • g=0.98; • Graphics^ g1; • g1= this->CreateGraphics(); • Pen^ p1 =gcnew Pen(System::Drawing::Color::Red); • x=0; • y=150; • for (i=0;i<8;i++)

  18. { • for(pi=0;pi<8*3.13;pi=pi+0.02) • { p1->Color =Color::Red ; • p1->Width = 2.0F; • y=100*(Math::Sin(pi)); • x=pi*10; • g1->DrawEllipse (p1,x,y+100,50,50); • for(x=0;x<1000000;x+=10); • y=100*(Math::Sin (pi-0.02)); • x=pi*10; • p1->Color=this->BackColor ; • g1->DrawEllipse (p1,x,y+100,50,50); • } • y=y*0.6; • } • delete p1;delete g1; } • };

  19. 图形动画

  20. 10.2 图像的动态显示 • 所谓图像的动态显示,系指图像以某种方式徐徐切入界面。实现图像的动态显示的方法很多,本节只作简单的介绍。

  21. 10.2.1 利用Graphics.DrawImage 方法 • 第3章介绍了Graphics.DrawImage 方法的基本使用方法,这里用具体实例来说明Graphics.DrawImage 方法在实现图像的动态显示方面的应用。

  22. 1.界面设计 • 如图10-10所示。 在窗体上添加两个pictureBox控件和相应几个按钮如图设计其标题属性。

  23. 2。程序设计 • (1)左到右拉伸效果 • 图片框1中输入的图像以左到右拉伸方式动态显示到图片框2中。程序设计如下。 • private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { • int x,y, pw, ph ; • Graphics^g1=pictureBox2->CreateGraphics(); • Bitmap^box1 =gcnew Bitmap(this->pictureBox1->Image); • //把图片框中的图片给一个bitmap 类型 • Bitmap^box2 =gcnew Bitmap(this->pictureBox2->Image); • pw =this->pictureBox1->Width; • ph =this->pictureBox1->Height; • for (x=0; x<=pw;x++) • { g1->DrawImage (box1,0,0,x,ph); • } }

  24. 中间向四周扩散效果 • 图片框1中输入的图像以中间向四周扩散的方式动态显示到图片框2中。程序设计如下。 • private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { • int x,y, pw, ph ; • Graphics^g1=pictureBox2->CreateGraphics(); • Bitmap^box1 =gcnew Bitmap(this->pictureBox1->Image); • Bitmap^box2 =gcnew Bitmap(this->pictureBox2->Image); pw =this->pictureBox1->Width; • ph =this->pictureBox1->Height; • for(x=0;x<120;x++) • {Rectangle destRect =Rectangle( pw/2-x,ph/2-x,2*x,2*x);//目地图像 • Rectangle srcRect =Rectangle(0,0,pw,ph );//取原图像 • GraphicsUnit units = GraphicsUnit::Pixel; • g1->DrawImage(box1, destRect, srcRect, units); • } • }

  25. 旋转效果 • 图片框1中输入的图像以旋转方式动态显示到图片框2中。程序设计如下。 • private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { int x,y, pw, ph ; • Graphics^g1=pictureBox2->CreateGraphics(); • Bitmap^box1 =gcnew Bitmap(this->pictureBox1->Image); • Bitmap^box2 =gcnew Bitmap(this->pictureBox2->Image); pw =this->pictureBox1->Width; • ph =this->pictureBox1->Height; • for(x=-100;x<120;x++) • {Rectangle destRect =Rectangle( 0,ph/2-x,pw,2*x);//目地图像 • Rectangle srcRect =Rectangle(0,0,pw,ph );//取原图像 • GraphicsUnit units = GraphicsUnit::Pixel; • g1->DrawImage(box1, destRect, srcRect, units); • } }

  26. (5)中间向两边拉伸效果 • 图片框1中输入的图像以中间向两边拉伸的方式动态显示到图片框2中。程序设计如下。 • private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { int x,y, pw, ph ; • Graphics^g1=pictureBox2->CreateGraphics(); • Bitmap^box1 =gcnew Bitmap(this->pictureBox1->Image); • Bitmap^box2 =gcnew Bitmap(this->pictureBox2->Image); • pw =this->pictureBox1->Width; • ph =this->pictureBox1->Height; • for(x=0;x<110;x++) • {Rectangle destRect =Rectangle( 0,ph/2-x,pw,2*x); • Rectangle srcRect =Rectangle(0,0,pw,ph ); • GraphicsUnit units = GraphicsUnit::Pixel; • g1->DrawImage(box1, destRect, srcRect, units); • } }

  27. [例10-4]幻灯片切换效果 • 项目界面设计 • 建立一新窗体,在窗体上添加5个pictureBox控件用image属性加载图像,设pictureBox2~pictureBox5的visible属性False,添加Button控件并将其Caption属性改为“动态显示”。窗体如图10-11所示。

  28. 2 程序设计 • private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { int x,i, pw, ph ; • Graphics^g1=pictureBox1->CreateGraphics(); • Color^c=gcnew Color (); • Bitmap^box1 =gcnew Bitmap(this->pictureBox1->Image); //把图片框中的图片给一个bitmap 类型 • array< Bitmap^>^bit= gcnew array<Bitmap^>(5);//建立一图片数组 • bit[0]=gcnew Bitmap( pictureBox1->Image) ; //以下为图片数组存入图片 • bit[1]=gcnew Bitmap (pictureBox2->Image) ; • bit[2]=gcnew Bitmap (pictureBox3->Image) ; • bit[3]=gcnew Bitmap (pictureBox4->Image) ; • bit[4]=gcnew Bitmap (pictureBox5->Image) ;

  29. pw =this->pictureBox1->Width+50 ; • ph =this->pictureBox1->Height+50 ; • for (i=1;i<5;i++) • { • for (x=0; x<=ph;x++) • { • g1->DrawImage (bit[i-1],x,x,pw-x,ph-x); //用DrawImage把图片缩小 • g1->DrawImage (bit[i],0,0,x,x);//用DrawImage把图片放大 • } • } • }

  30. 10.2.2 像素编程法 • [例10-4] 图像动态显示 • 1.界面设计 • 本例界面设计如图10-13所示。在窗体上设置两个PictureBox、一个打开文件通用对话框和两个命令按钮。两个命令按钮中一个用于在PictureBox1内输入图像,一个为切换动作按钮。在PictuerBox2中预先输入一幅图像。

  31. (1)输入图像 • 在PictureBox1输入一幅图像。程序设计如下: • private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { • OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog; • openFileDialog1->FilterIndex = 2; • openFileDialog1->RestoreDirectory = true; • openFileDialog1->Filter= "Bmp File(*.bmp)|*.bmp"; • if ( openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK && openFileDialog1->FileName->Length > 0 ) • { • pictureBox1->Load(openFileDialog1->FileName); • } • }

  32. (2)上下对接 • 图片框1中输入的图像从图片框2的上部和下部进入进行对接并显示在图片框2中。程序设计如下: • private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { Color^c=gcnew Color (); Bitmap^box1 =gcnew Bitmap(this->pictureBox1->Image); Bitmap^box2 =gcnew Bitmap(this->pictureBox2->Image); • int r,g,b,x,i; x = 0; • while(x <= pictureBox1->Height /2) • { • for (i=0 ; i<=pictureBox1->Width - 1;i+=1) • { • c=box1->GetPixel(i,x); • r=c->R; • g=c->G; • b=c->B

  33. Color c1= Color::FromArgb(r,g,b) ; • box2->SetPixel (i,x,c1); • } • for (i=0 ; i<=pictureBox1->Width - 1;i+=1) • {c=box1->GetPixel(i,pictureBox1->Height - 1-x); • r=c->R; • g=c->G; • b=c->B; • Color c1= Color::FromArgb(r,g,b) ; • box2->SetPixel (i,pictureBox1->Height - 1-x,c1); • } • x = x + 1; • pictureBox2->Refresh(); //刷新 • pictureBox2->Image=box2; } • }

  34. (3) 左右对接 • 图片框1中输入的图像从图片框2的左侧和右侧进入进行对接并显示在图片框2中。程序设计如下: • private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { • Color^c=gcnew Color (); • Bitmap^box1 =gcnew Bitmap(this->pictureBox1->Image); • Bitmap^box2 =gcnew Bitmap(this->pictureBox2->Image); • int rr,gg,bb,x,i; • x = 0; • while(x <= pictureBox1->Width /2) • { • for (i=0 ; i<=pictureBox1->Height- 1;i+=1) • { • c=box1->GetPixel(x,i); • rr=c->R; • gg=c->G; • bb=c->B;

  35. Color c1= Color::FromArgb(rr,gg,bb) ; • box2->SetPixel (x,i,c1); • } • for (i=0 ; i<=pictureBox1->Height- 1;i+=1) • { • c=box1->GetPixel(pictureBox1->Width - 1-x,i); • rr=c->R; • gg=c->G; • bb=c->B; • Color c1= Color::FromArgb(rr,gg,bb) ; • box2->SetPixel (pictureBox1->Width - 1-x,i,c1); • } • x = x + 1; • pictureBox2->Refresh(); //刷新 • pictureBox2->Image=box2; } • }

  36. 10.3 设计范例与练习题 • 【1】使用DrawImage实现动画 • 界面设计如图10-14所示。

  37. 代码设计如下. • private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { • int x,i, pw, ph ; • Graphics^g1=pictureBox1->CreateGraphics(); • Color^c=gcnew Color (); • Bitmap^box1 =gcnew Bitmap(this->pictureBox1->Image); array< Bitmap^>^bit= gcnew array<Bitmap^>(5);//建立一图片数组 • bit[0]=gcnew Bitmap( pictureBox1->Image) ; • bit[1]=gcnew Bitmap (pictureBox2->Image) ; • bit[2]=gcnew Bitmap (pictureBox3->Image) ; • bit[3]=gcnew Bitmap (pictureBox4->Image) ; • bit[4]=gcnew Bitmap (pictureBox5->Image)

  38. pw =this->pictureBox1->Width+50 ; • ph =this->pictureBox1->Height+50 ; • for (i=1;i<5;i++) • { • for (x=0; x<=pw/2;x++) • { • RectangleF destRect =RectangleF( 0, 0, pw/2+x, ph); • RectangleF srcRect =RectangleF( pw/2-x, 0, pw, ph); • GraphicsUnit units = GraphicsUnit::Pixel; • g1->DrawImage (bit[i],destRect, srcRect, units); • } • if (i<4) • g1->Clear (Color::White); • } • } • 程序运行后,图片从左向右进入界面。

  39. 【3】图形动画 • 界面设计如图10-15所示。

  40. 程序设计如下。 • private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { • timer1->Interval = 100; • timer1->Enabled = true; • } • private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) { • Graphics ^ g; • g = pictureBox1->CreateGraphics(); • Pen^ pen = gcnew Pen( Color::Black); • Pen^ pen1 = gcnew Pen(Color::Red); • Pen^ pen2 = gcnew Pen(Color::Blue); • Pen^ pen3 = gcnew Pen(Color::Green); • g->DrawLine(pen,0,100,600,100);

  41. if (x>=600) • x=0; • m=n%3; • switch (m) • { • case 0: • g->Clear(Color::LightYellow); • g->DrawLine(pen,0,100,600,100); • g->DrawEllipse(pen1,x,50,50,50); • break; • case 1: • //g->Clear(Color::LightYellow); • g->DrawLine(pen,0,100,600,100); • g->DrawEllipse(pen2,x,50,50,50); • break;

  42. case 2: • //g->Clear(Color::LightYellow); • g->DrawLine(pen,0,100,600,100); • g->DrawEllipse(pen3,x,50,50,50); • break; • } • x++; • n++; • } • }; • }

  43. 程序运行后,单击“动画”按钮,如图10-16所示,小环徐徐从左向右滚动。程序运行后,单击“动画”按钮,如图10-16所示,小环徐徐从左向右滚动。 图10-16 图形动画

  44. 【4】时钟 • 设计如图10-17所示。

  45. private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) { • Graphics^g; • g=this->pictureBox1->CreateGraphics(); • this->pictureBox1->Refresh(); • Pen^p1 =gcnew Pen(Color::Black); • p1->Width=8.0; • Pen^p2 =gcnew Pen(Color::Black); • p2->Width=5.0; • Pen^ p3 =gcnew Pen(Color::Red); • p3->Width=3.0; • String^ t; • double x1, x2, x3; • double ss, hh, mm; • int x, y, a1, b1, a2, b2, a3, b3; • x = pictureBox1->Width; • y = pictureBox1->Height;

  46. label1->Text =System::DateTime::Now.ToLongTimeString(); • t = label1->Text; • ss = double::Parse(t->Substring(t->Length - 2, 2)); • mm = double::Parse(t->Substring(t->Length - 5, 2)); • if (t->Length == 7) • { • hh = double::Parse(t->Substring(0, 1)); • } • else • { • hh = double::Parse(t->Substring(0, 2)); • } • x1 = -90 + ss * 6; • x2 = -90 + ((mm + ss / 60) * 6); • x3 = -90 + ((hh + mm / 60) * 30);

More Related