• WinForm 分屏 [ WinForm | Panel | 视频监控分屏 ]



    前言
          视频监控的分屏技术实际上就是通过动态Panel + 动态指定其Location和Size来实现的,还需要一个计算分屏数目的算法,本文将弥补视频监控系列中动态分屏的功能,权当续文吧 : )

    正文
          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.      分屏算法
            /// <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(238);

                
    //模数
                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  修改一下方法,更加好用点

            /// <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;
            }

      

        5.2  示例代码  2010-5-25

          分屏示例下载


    结束语
          这个功能也是在最近代码重构的时候补上来的,也欢迎大家提供其他算法来分屏 :)


    本博与本文相关文章
            1.        视频监控系列文章

  • 相关阅读:
    整数反转
    最长公共前缀
    罗马数字转整数
    单点登录
    VMware Workstation虚拟机密钥
    Pytest 用例内部执行顺序
    判断是不是回文数
    python端口IP字符串是否合法
    python求二叉树深度
    有两个字符串类型的数字,实现一个方法将它们进行相加,并返回相加后的数值。
  • 原文地址:https://www.cnblogs.com/over140/p/1540410.html
Copyright © 2020-2023  润新知