• 大小: 1.23M
    文件类型: .rar
    金币: 1
    下载: 0 次
    发布日期: 2020-12-14
  • 语言: C#
  • 标签: winform  C#  c  图像  ORM  

资源简介

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个文件信息

评论

共有 条评论