資源簡介
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; } }
代碼片段和文件信息
using?System;
using?System.Drawing;
using?System.Windows.Forms;
using?System.Runtime.InteropServices;
class?Alpha_Win32
{
????public?enum?Bool
????{
????????False?=?0
????????True
????};
????[StructLayout(LayoutKind.Sequential)]
????public?struct?Point
????{
????????public?Int32?x;
????????public?Int32?y;
????????public?Point(Int32?x?Int32?y)?{?this.x?=?x;?this.y?=?y;?}
????}
????[StructLayout(LayoutKind.Sequential)]
????public?struct?Size
????{
????????public?Int32?cx;
????????public?Int32?cy;
????????public?Size(Int32?cx?Int32?cy)?{?this.cx?=?cx;?this.cy?=?cy;?}
????}
????[StructLayout(LayoutKind.Sequential?Pack?=?1)]
????struct?ARGB
????{
????????public?byte?Blue;
????????public?byte?Green;
????????public?byte?Red;
????????public?byte?Alpha
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????文件???????5823??2018-01-06?10:59??四點變形圖像\test1\test1\3D_effect\Cube.cs
?????文件???????6413??2018-01-06?10:59??四點變形圖像\test1\test1\3D_effect\FreeTransform.cs
?????文件???????4761??2018-01-06?10:59??四點變形圖像\test1\test1\3D_effect\ImageData.cs
?????文件???????3893??2018-01-06?10:59??四點變形圖像\test1\test1\3D_effect\Math3D.cs
?????文件???????2926??2018-01-06?10:59??四點變形圖像\test1\test1\3D_effect\Vector.cs
?????文件???????4602??2018-01-21?19:42??四點變形圖像\test1\test1\AlphaForm.cs
?????文件????????189??2018-01-21?16:42??四點變形圖像\test1\test1\App.config
?????文件?????623059??2018-01-21?19:56??四點變形圖像\test1\test1\bin\Debug\1.png
?????文件?????616056??2018-01-21?19:58??四點變形圖像\test1\test1\bin\Debug\2.png
?????文件??????27136??2018-01-21?23:36??四點變形圖像\test1\test1\bin\Debug\test1.exe
?????文件????????189??2018-01-21?16:42??四點變形圖像\test1\test1\bin\Debug\test1.exe.config
?????文件??????67072??2018-01-21?23:36??四點變形圖像\test1\test1\bin\Debug\test1.pdb
?????文件??????11723??2018-01-21?23:36??四點變形圖像\test1\test1\Form1.cs
?????文件???????8509??2018-01-21?21:59??四點變形圖像\test1\test1\Form1.Designer.cs
?????文件???????5817??2018-01-21?21:59??四點變形圖像\test1\test1\Form1.resx
?????文件????????517??2018-01-21?16:42??四點變形圖像\test1\test1\Program.cs
?????文件???????1308??2018-01-21?16:42??四點變形圖像\test1\test1\Properties\AssemblyInfo.cs
?????文件???????2823??2018-01-21?16:42??四點變形圖像\test1\test1\Properties\Resources.Designer.cs
?????文件???????5612??2018-01-21?16:42??四點變形圖像\test1\test1\Properties\Resources.resx
?????文件???????1092??2018-01-21?16:42??四點變形圖像\test1\test1\Properties\Settings.Designer.cs
?????文件????????249??2018-01-21?16:42??四點變形圖像\test1\test1\Properties\Settings.settings
?????文件???????3927??2018-01-21?23:34??四點變形圖像\test1\test1\test1.csproj
?????文件???????1114??2018-01-21?16:42??四點變形圖像\test1\test1.sln
?????目錄??????????0??2018-01-21?23:36??四點變形圖像\test1\test1\bin\Debug
?????目錄??????????0??2018-01-21?23:33??四點變形圖像\test1\test1\bin\Release
?????目錄??????????0??2018-01-21?23:37??四點變形圖像\test1\test1\obj\Debug
?????目錄??????????0??2018-01-20?20:52??四點變形圖像\test1\test1\3D_effect
?????目錄??????????0??2018-01-21?23:33??四點變形圖像\test1\test1\bin
?????目錄??????????0??2018-01-21?16:42??四點變形圖像\test1\test1\obj
?????目錄??????????0??2018-01-21?16:42??四點變形圖像\test1\test1\Properties
............此處省略6個文件信息
- 上一篇:C# socket實現客戶端與服務端通信
- 下一篇:C# Bootsrap分頁
評論
共有 條評論