Graphics 绘制波形

24 篇文章 0 订阅
#region  绘制波形

        //private Graphics objGraphics; //Graphics 类提供将对象绘制到显示设备的方法
        //private Bitmap objBitmap; //位图对象
        /// <summary>
        /// 绘制波形
        /// </summary>
        /// <param name="objGraphics">位图对象</param>
        /// <param name="start">开始的点</param>
        /// <param name="end">结束的点</param>
        /// <param name="listCurveChan">具体内容数值</param>
        private void DrawCurveEx(Graphics objGraphics, Point start, Point end, List<WMODEL_EXTENDSTRUCT.MSG_VIDEO_RECORD_EXTEND> listCurveChan)
        {   
            Dictionary<string, float> dicKeyValue = new Dictionary<string, float>();
            List<string> listName = new List<string>();
            List<float> listVaule = new List<float>();
            foreach (var item in listCurveChan)
            {
                dicKeyValue.Add(item.struDvrChan.szName, item.fValue);
            }

            InitializeGraph(ref objGraphics, start, end, dicKeyValue);
            DrawContent(ref objGraphics, start, end, dicKeyValue);
        }
       
        #region 初始化和填充图像区域,画出边框,初始标题

        private int Width = 0; //图像宽度
        private int Height = 0; //图像高度
        //private float XSlice = 50; //X轴刻度宽度
        //private float YSlice = 50; //Y轴刻度宽度
        //private float YSliceValue = 20; //Y轴刻度的数值宽度
        //private float YSliceBegin = 0; //Y轴刻度开始值
        private float Tension = 0.5f;//设置张力
        private string Title = "测温"; //Title
        private string XAxisText = "名称"; //X轴说明文字
        private string YAxisText = "℃"; //Y轴说明文字

        //private string[] m_Keys = new string[] { "一月", "二月", "三月", "四月" }; //键
        private int[] m_Values = new int[] { 0, 20, 40,60,80,100 };//值

        private Color BgColor = Color.Snow; //背景
        private Color TextColor = Color.White; //文字颜色
        private Color BorderColor = Color.White; //整体边框颜色
        private Color AxisColor = Color.White; //轴线颜色
        private Color AxisTextColor = Color.White; //轴说明文字颜色
        private Color SliceTextColor = Color.White; //刻度文字颜色
        private Color SliceColor = Color.White; //刻度颜色
        private Color CurveColor = Color.Green; //曲线颜色      

        private void InitializeGraph(ref Graphics objGraphics, Point start, Point end,Dictionary<string, float> dicKeyValue)
        {
            Point p1 = new Point(start.X, end.Y);
            Point p2 = new Point(end.X, start.Y);
            Width = end.X - start.X;
            Height = end.Y - start.Y;

            //根据给定颜色(LightGray)填充图像的矩形区域 (背景)
            //objGraphics.DrawRectangle(new Pen(BorderColor, 1), start.X, start.Y, Width, Height);
            //objGraphics.FillRectangle(new SolidBrush(BgColor), start.X + 1, start.Y + 1, Width - 2, Height - 2);//填充颜色
            
            //画X轴,pen,x1,y1,x2,y2 注意图像的原始X轴和Y轴计算是以左上角为原点,向右和向下计算的
            //objGraphics.DrawLine(new Pen(new SolidBrush(AxisColor), 1), start.X, start.Y + Height, start.X + Width, start.Y + Height);
            objGraphics.DrawLine(new Pen(new SolidBrush(AxisColor), 1), start.X, end.Y, end.X, end.Y);
            //画Y轴,pen,x1,y1,x2,y2
            objGraphics.DrawLine(new Pen(new SolidBrush(AxisColor), 1), start.X, start.Y, start.X, end.Y);

            //初始化轴线说明文字
            SetAxisText(ref objGraphics,start,end);

            #region 横纵坐标
            /*
            float xRange = 1440;   //X轴最大范围(0-1440)
            float yRange = 500;    //Y轴最大范围(0-500)

            int XScaleCount = 24;          //X轴刻度线数量
            int YScaleCount = 10;          //Y轴刻度线数量

            int HorizontalMargin = 50;     //横水平边距
            int VerticalMargin = 80;                                     //竖垂直边距
            Pen penScale = new Pen(SliceColor, 1);
            int fontSize = 8;
            for (int i = 0; i <= XScaleCount; i++)
            {
                int x = i * (Width / XScaleCount) + start.X;
                //objGraphics.DrawLine(penScale, x, start.Y, x,end.Y);
                string lbl = (i * (xRange / XScaleCount)).ToString();
                if (xRange == 1440)   //如果按照一天分钟时间显示
                    lbl = (i * (xRange / XScaleCount) / 60).ToString();
                if (i != 0)
                { objGraphics.DrawString(lbl, new Font("微软雅黑", fontSize, FontStyle.Regular), new SolidBrush(AxisColor), new Point(x - fontSize, end.Y + VerticalMargin / 9)); }
            }
            for (int i = 0; i <= YScaleCount; i++)
            {
                int y = end.Y - (i * (Height / YScaleCount));
                //objGraphics.DrawLine(penScale, start.X, y,end.X, y);
                string lbl = (i * (yRange / YScaleCount)).ToString();
                objGraphics.DrawString(lbl, new Font("微软雅黑", fontSize, FontStyle.Regular), new SolidBrush(AxisColor), new Point(start.X - (fontSize * lbl.Length) - HorizontalMargin / 9, y - fontSize / 2));
            }
             * */
            #endregion

            if (dicKeyValue == null || dicKeyValue.Count == 0) return;
            //初始化X轴上的刻度和文字
            SetXAxisEx(ref objGraphics, start, end,dicKeyValue);           
            //初始化Y轴上的刻度和文字
            SetYAxisEx(ref objGraphics, start, end, dicKeyValue);
       
            //初始化标题
            CreateTitle(ref objGraphics,start,end);           
        }

        #region  坐标轴

        float XSpace = 10;//图像左右距离边缘距离
        float YSpace = 10;    //图像上下距离边缘距离

        //初始化标题
        private void CreateTitle(ref Graphics objGraphics, Point start, Point end)
        {
            int Width = end.X - start.X;
            objGraphics.DrawString(Title, new Font("宋体", 12), new SolidBrush(TextColor), start.X + Width/2,start.Y);
        }

        //初始化轴线说明文字
        private void SetAxisText(ref Graphics objGraphics, Point start, Point end)
        {
            //X轴说明文字
            objGraphics.DrawString(XAxisText, new Font("宋体", 10), new SolidBrush(AxisTextColor), end.X-20, end.Y - 20);

            //Y轴说明文字
            int X = start.X-16 ;
            int Y = start.Y - 4;
            for (int i = 0; i < YAxisText.Length; i++)
            {
                objGraphics.DrawString(YAxisText[i].ToString(), new Font("宋体", 10), new SolidBrush(AxisTextColor), X, Y);
                Y += 15;
            }
        }
              
        //初始化X轴上的刻度和文字
        private void SetXAxisEx(ref Graphics objGraphics, Point start, Point end, Dictionary<string, float> dicKeyValue)
       {
           int chan = dicKeyValue.Count;//多少通道
           List<string> listKey = new List<string>();
           foreach (var item in dicKeyValue)
           {
               listKey.Add(item.Key);
           }
           //Point p1 = new Point(start.X, end.Y);
           //Point p2 = new Point(end.X, start.Y);
           //Width = end.X - start.X ;
           //Height = end.Y - start.Y;

           int iSliceCount = 0;//数组索引
          
           float iWidth = Width - 2 * XSpace  ; //要画刻度的长度
           float Scale = iWidth / (float)chan;//一段多长

            //绘制横坐标文字         
           for (int i = 0; i < chan; i ++)
           {
               float x = start.X + XSpace + Scale * i;
                //这里显示X轴刻度
               if (iSliceCount <= listKey.Count - 1)
               {
                   #region
                   if (chan > 5)
                   {
                       if (iSliceCount == 0)
                       {
                           objGraphics.DrawString(listKey[iSliceCount].ToString(), new Font("宋体", 10), new SolidBrush(SliceTextColor), x, end.Y);
                           //画网格虚线
                           //Pen penDashed = new Pen(new SolidBrush(AxisColor));
                           //penDashed.DashStyle = DashStyle.Dash;
                           //objGraphics.DrawLine(penDashed, x, start.Y, x, end.Y);
                       }
                       else
                       {
                           if ((iSliceCount + 1) % 5 == 0)
                           {
                               objGraphics.DrawString(listKey[iSliceCount].ToString(), new Font("宋体", 10), new SolidBrush(SliceTextColor), x, end.Y);
                               //画网格虚线
                               //Pen penDashed = new Pen(new SolidBrush(AxisColor));
                               //penDashed.DashStyle = DashStyle.Dash;
                               //objGraphics.DrawLine(penDashed, x, start.Y, x, end.Y);
                           }
                       }
                   }
                   else
                   {
                       objGraphics.DrawString(listKey[iSliceCount].ToString(), new Font("宋体", 10), new SolidBrush(SliceTextColor), x, end.Y);
                       //画网格虚线
                       //Pen penDashed = new Pen(new SolidBrush(AxisColor));
                       //penDashed.DashStyle = DashStyle.Dash;
                       //objGraphics.DrawLine(penDashed, x, start.Y, x, end.Y);
                   }                  

                   #endregion
               }
               else
               {
                   //超过范围,不画任何刻度文字
               }
                iSliceCount++;
                if (x - start.X > Width)
                {
                    break;
                }            
                x = start.X + XSpace + Scale * i;
                #region 如果横坐标大于5个就5个为1个
                if (chan > 5)
                {
                    if (i == 0)
                    {
                        objGraphics.DrawLine(new Pen(new SolidBrush(SliceColor)), x, end.Y + 5, x, end.Y - 5);
                    }
                    else
                    {
                        if ((i + 1) % 5 == 0)
                        {
                            objGraphics.DrawLine(new Pen(new SolidBrush(SliceColor)), x, end.Y + 5, x, end.Y - 5);
                        }
                    }
                }
                else
                {
                    objGraphics.DrawLine(new Pen(new SolidBrush(SliceColor)), x, end.Y + 5, x, end.Y - 5);
                }
               #endregion                                                                                                                                                                                                                                                                                                                             
           }        

       }
        //初始化Y轴上的刻度和文字
        private void SetYAxisEx(ref Graphics objGraphics, Point start, Point end,Dictionary<string, float> dicKeyValue)
        {
            int nIn = 5;
            List<float> listF = new List<float>();
            foreach (var item in dicKeyValue.Values)
            {
                listF.Add(item);
            }
            //Point p1 = new Point(start.X, end.Y);
            //Point p2 = new Point(end.X, start.Y);
            //Width = end.X - start.X;
            //Height = end.Y - start.Y;

            float iHeight = Height -  YSpace; //将要画刻度的长度分段 ,刻度线。
            float Scale = iHeight / (float)nIn;//每段多长

            float fMax = 0;
            for (int j = 0; j < listF.Count; j++)
            {
                if (listF[j] > fMax)
                {
                    fMax = listF[j];
                }
            }
            if (fMax < 1)
                fMax = 1;

            fMax = fMax * 3 / 2;

            for (int i = 0; i < nIn ; i++)
            {
                float scale = (fMax / nIn) * i;//每一段的距离
                float y = end.Y - YSpace - Scale * i;
                float x = start.X - 30;
                //这里显示Y轴刻度
                objGraphics.DrawString(scale.ToString(), new Font("宋体", 10), new SolidBrush(SliceTextColor), x, y);
                //画网格虚线
                //Pen penDashed = new Pen(new SolidBrush(AxisColor));
                //penDashed.DashStyle = DashStyle.Dash;
                //objGraphics.DrawLine(penDashed, start.X, y, end.X, y);
                if (y - start.Y > Height)
                {
                    break;
                }
                //y = start.Y + YSpace + Scale * i;                
                objGraphics.DrawLine(new Pen(new SolidBrush(SliceColor)), start.X + 5, y, start.X - 5, y);
            }        

        }

        /// <summary>
        /// 画曲线	   
        /// </summary>
        /// <param name="objGraphics"></param>
        private void DrawContent(ref Graphics objGraphics, Point start, Point end, Dictionary<string, float> dicKeyValue)
        {
            if (dicKeyValue.Count == 0 || dicKeyValue == null) return;
            List<float> listF = new List<float>();
            foreach (var item in dicKeyValue.Values)
            {
                listF.Add(item);
            }

            float fMax = 0;
            for (int j = 0; j < listF.Count; j++)
            {
                if (listF[j] > fMax)
                {
                    fMax = listF[j];
                }
            }

            if (fMax < 1)
                fMax = 1;

            fMax = fMax * 3 / 2;

            Color clrCurrentColor = Color.Red;

            Pen CurvePen = new Pen(clrCurrentColor, 2);
            PointF[] CurvePointF = new PointF[listF.Count];
            float keys = 0;//X轴坐标
            float values = 0;//Y轴坐标

            //X轴刻度长度
            float iWidth = Width - 2 * XSpace; //将要画刻度的长度分段,并乘以50,以10为单位画刻度线。
            float XScale = iWidth / (float)listF.Count;//一段多长

            //Y轴刻度长度           
            //float iHeight = Height - 2 * YSpace; //将要画刻度的长度分段 ,刻度线。
            //float YScale = iHeight / (float)m_Values.Length;//每段多长

            for (int i = 0; i < listF.Count; i++)
            {
                keys = start.X + XScale * i + XSpace;

                float y = listF[i] / fMax * (Height - YSpace);
                values = end.Y - YSpace - y;
                //values = start.Y + (Height - YSpace) + YSliceBegin - YScale * (listF[i] / YSliceValue);
                CurvePointF[i] = new PointF(keys, values);
            }
            objGraphics.DrawCurve(CurvePen, CurvePointF, Tension);
        }

        #endregion   
       
        #endregion

        #endregion

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用ComputeShader来计算波形的值,并将结果传递到GPU上进行绘制。下面是一些简单的示例代码: 首先,需要定义一个ComputeShader: ```hlsl #pragma kernel CSMain RWTexture2D<float4> result; [numthreads(8, 8, 1)] void CSMain (uint3 id : SV_DispatchThreadID) { float x = (float)id.x / (float)result.GetWidth(); float y = (float)id.y / (float)result.GetHeight(); float value = sin(x * 10.0f) * cos(y * 10.0f); result[id.xy] = float4(value, value, value, 1.0f); } ``` 这个ComputeShader的作用是计算在屏幕上绘制一个波形图所需的值。在这个示例中,使用了sin和cos函数来计算波形的值,并将结果存储在一个float4类型的纹理中。 接下来,需要在C#代码中创建一个RenderTexture,并将其绑定到ComputeShader中: ```csharp public class WaveformRenderer : MonoBehaviour { public ComputeShader computeShader; public Material material; public int textureSize = 512; private RenderTexture waveformTexture; private void Start() { waveformTexture = new RenderTexture(textureSize, textureSize, 0, RenderTextureFormat.ARGBFloat); waveformTexture.enableRandomWrite = true; waveformTexture.Create(); int kernelHandle = computeShader.FindKernel("CSMain"); computeShader.SetTexture(kernelHandle, "result", waveformTexture); computeShader.Dispatch(kernelHandle, textureSize / 8, textureSize / 8, 1); material.SetTexture("_MainTex", waveformTexture); } private void OnRenderImage(RenderTexture source, RenderTexture destination) { Graphics.Blit(source, destination, material); } } ``` 在这个示例中,使用了一个Material来将计算出的纹理绘制到屏幕上。在Start()方法中,首先创建了一个RenderTexture,并将其设置为可写。然后将其绑定到ComputeShader中,并使用Dispatch()方法来执行ComputeShader。最后,将计算出的纹理存储在Material中,并在OnRenderImage()方法中将其绘制到屏幕上。 这就是一个简单的使用ComputeShader绘制波形图的示例。你可以根据自己的需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值