zoukankan      html  css  js  c++  java
  • 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;
            }
  • 相关阅读:
    通过 AWS CLI 操作 AWS S3
    AWS S3文件存储服务器搭建(新)
    Vertx 接入MongoDB (九)
    Vertx 接入Redis (八)
    Vertx Mysql数据库优化 (七)
    Vertx 接入Mysql数据库 (六)
    Vertx 实现webapi实战项目(五)
    Vertx 实现webapi实战项目(四)
    Vertx 实现webapi实战项目(三)
    正则表达式:元字符(基本可用来匹配的字符)
  • 原文地址:https://www.cnblogs.com/glzgc/p/7940464.html
Copyright © 2011-2022 走看看