前言
视频监控的分屏技术实际上就是通过动态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( 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 修改一下方法,更加好用点
/// <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; } 本文转自over140 51CTO博客,原文链接:http://blog.51cto.com/over140/586624,如需转载请自行联系原作者