天天看點

WinForm 分屏 [ WinForm | Panel | 視訊監控分屏 ]

1. 先“上菜”再講做法:——上圖~~

2.      動态Panel

        /// <summary>

        /// 動态建立面闆

         /// </summary>

        /// <param name="xy">Panel的XY坐标</param>

        /// <param name="wh">Panel的大小</param>

        private Panel CreatePanel(Point xy, Size wh)

        {

            Panel panel = new Panel();

            panel.BackColor = System.Drawing.Color.Transparent;

            panel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;

            panel.Location = xy;

            panel.Name = string.Concat("pVideo");

            panel.Size = wh;

            panel.TabIndex = 0;

            panel.BackColor = Color.Black;

            return panel;

        }

3.      分屏算法

        /// 根據通道數動态計算Panel的坐标和大小

        /// </summary>

        /// <param name="channelCount">通道數</param>

        /// <param name="xy">傳回運算後每個Panel的坐标</param>

        /// <param name="wh">傳回運算後每個Panel的大小</param>

        private void MathDynamicPanel(int channelCount, out Point[] xy, out Size[] wh)

            xy = new Point[channelCount];

            wh = new Size[channelCount];

            //第一個Panel的起始坐标——不變

            xy[0] = new Point(2, 38);

            //模數

            int modulo;

            if (channelCount <= 4)

                modulo = 2;

            else if (channelCount <= 9)

                modulo = 3;

            else if (channelCount <= 16)

                modulo = 4;

            else if (channelCount <= 25)

                modulo = 5;

            else if (channelCount <= 36)

                modulo = 6;

            else if (channelCount <= 49)

                modulo = 7;

            else// if (channelCount <= 64)

                modulo = 8;

            int width, height;

            //610 為整個預覽區的寬

            width = (610 - modulo * 1) / modulo;

            //532 為整個預覽區的高

            height = (532 - modulo * 1) / modulo;

            for (int i = 0; i < channelCount; i++)

            {

                wh[i] = new Size(width, height);

                if (i > 0)

                {

                    //同一行的Y坐标相等

                    //同一列的X坐标相等

                    if (i % modulo == 0)

                        xy[i] = new Point(xy[i - modulo].X, xy[i - modulo].Y + height + 1);

                    else

                        xy[i] = new Point(xy[i - 1].X + width + 1, xy[i - 1].Y);

                }

            }

            代碼說明:

                  a).      采用平方算法,即4個頭4個Panel(2 ^ 2),8個頭9個Panel(3 ^ 3),算是比較簡單也滿足基本需求的算法了。

                  b).      注意需要固定左上角頂點坐标和總面積,即(2,38)和610,532,這個可以根據自己的時間情況加以修改,可以定義成const int 就行。

                  c).      注意裡面算坐标的時候有+1,這個是Panel之間的間隙。

4.      使用例子

        在Form_Load中加入如下代碼:

            Point[] xy;

            Size[] wh;

            int channel = 8;

            //計算面闆坐标

            MathDynamicPanel(channel, out xy, out wh);

            //建立面闆

            for (int i = 0; i < channel; i++)

                this.Controls.Add(CreatePanel(xy[i], wh[i]));

            運作即可見到截圖中的樣子,最大支援64個螢幕,滿足基本需求,自己加上放大、縮小和全屏的代碼功能就比較完整了。

5.文章更新維護

    5.1  2010-5-22  修改一下方法,更加好用點

        /// 計算視訊面闆位置和面積

        /// <param name="channelCount"></param>

        /// <param name="TotalSquare">總面積和坐标</param>

        /// <returns></returns>

        private IList<Rectangle> CalcPanelRectangle(int channelCount, Size TotalArea)

            IList<Rectangle> result = new List<Rectangle>();

            else if (channelCount > 64)

            else

                modulo = (int)Math.Ceiling(Math.Sqrt(channelCount));         //平方根

            //單個畫面大小

            width = (TotalArea.Width - modulo * 1) / modulo;

            height = (TotalArea.Height - modulo * 1) / modulo;

                Rectangle rect = new Rectangle();

                rect.Width = width;

                rect.Height = height;

                if (i % modulo == 0)

                    rect.X = 1;

                    if (i == 0)

                        rect.Y = 1;

                        rect.Y = result[i - modulo].Y + height + 1;

                else

                    rect.X = result[i - 1].X + width + 1;

                    rect.Y = result[i - 1].Y;

                result.Add(rect);

            return result;

    5.2  示例代碼  2010-5-25

繼續閱讀