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