winform分屏(视频监控分屏)

转载自:http://www.cnblogs.com/over140/category/172369.html

视频监控的分屏技术实际上就是通过动态Panel + 动态指定其Location和Size来实现的,还需要一个计算分屏数目的算法。

动态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;
        }

分屏算法:

       /// <summary>
        /// 根据通道数动态计算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);
                }
            }
        }
        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]));
            }

优化后的:

        /// <summary>
        /// 计算视频面板位置和面积
        /// </summary>
        /// <param name="channelCount"></param>
        /// <param name="TotalSquare">总面积和坐标</param>
        /// <returns></returns>
        private IList<Rectangle> CalcPanelRectangle(int channelCount, Size TotalArea)
        {
            IList<Rectangle> result = new List<Rectangle>();

            //模数
            int modulo;
            if (channelCount <= 4)
                modulo = 2;
            else if (channelCount > 64)
                modulo = 8;
            else
                modulo = (int)Math.Ceiling(Math.Sqrt(channelCount));         //平方根

            int width, height;

            //单个画面大小
            width = (TotalArea.Width - modulo * 1) / modulo;
            height = (TotalArea.Height - modulo * 1) / modulo;

            for (int i = 0; i < channelCount; i++)
            {
                Rectangle rect = new Rectangle();
                rect.Width = width;
                rect.Height = height;
                if (i % modulo == 0)
                {
                    rect.X = 1;
                    if (i == 0)
                        rect.Y = 1;
                    else
                        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;
        }
原文地址:https://www.cnblogs.com/glzgc/p/7940464.html