我有一块橡皮 2023-04-12 22:08 采纳率: 33.3%
浏览 54
已结题

使用WPF绘制地震图像

大家好,业余C#、WPF使用者;在这里我写了一个绘制地震波形图的窗体程序,遇到了一些问题:
1.数据量达到1000道左右时,很卡,即使数据量不多,一两百道也要等好一会儿才出结果
2.当该窗口被关闭时,没有释放内存
该函数如下:

readonly FileStream fileStream;
        readonly int nsamples;
        readonly int startTrace;
        readonly int endTrace;
        readonly float interval;
        double[,] datax;
        double[] datay;
        //readonly float maxAmpliude = 1;

        public Waveform(FileStream fileStream, int nsamples, int startTrace, int endTrace, float startTime, float endTime, float interval, int type)
        {
            //判断一下吧
            if (nsamples < 0)
            {
                MessageBox.Show("num. of samples error!");
                return;
            }
            if (startTrace <= 0)
            {
                MessageBox.Show("num. of start trace(s) error!");
                return;
            }
            if (endTrace < startTrace)
            {
                MessageBox.Show("num. of end trace(s) error!");
                return;
            }
            if (startTime < 0)
            {
                MessageBox.Show("num. of start time error!");
                return;
            }
            if (endTime < startTime)
            {
                MessageBox.Show("num. of end time error!");
                return;
            }
            if (interval < 0)
            {
                MessageBoxResult result = MessageBox.Show("num. of sample interval error!\ndo you want to replay it using 1 ms ?", "Requick", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.Yes)
                    interval = 1;
                else if (result == MessageBoxResult.No)
                    return;
            }

            InitializeComponent();

            this.fileStream = fileStream;
            this.nsamples = nsamples;
            this.startTrace = startTrace;
            this.endTrace = endTrace;
            this.interval = interval;

            int startSampl = Convert.ToInt32(startTime / interval);
            int endSampl = Convert.ToInt32(endTime / interval);
            this.datax = new double[endSampl - startSampl + 1, endTrace - startTrace + 1];
            this.datay = new double[endSampl - startSampl + 1];
            for (int i = 0; i < datay.Length; i++)
                datay[i] = startTime + i * interval;

            fileStream.Seek(3600 + (startTrace - 1) * (240 + 4 * nsamples), SeekOrigin.Begin);
            if (type == 1)
                IBMSwap(startSampl, endSampl);
            else if (type == 2)
                IBM(startSampl, endSampl);
            else if (type == 3)
                IEEESwap(startSampl, endSampl);
            else
                IEEE(startSampl, endSampl);

            ChartArea chartArea = new ChartArea();
            ChartPlot_Waveform.ChartAreas.Add(chartArea);

            for (int i = 0; i < endTrace - startTrace + 1; i++)
            {
                Series series = new Series();
                series.ChartType = SeriesChartType.Line;
                series.Color = System.Drawing.Color.Black;

                for (int j = 0; j < datay.Length; j++)
                {
                    series.Points.AddXY(datax[j, i], datay[j]);
                }
                ChartPlot_Waveform.Series.Add(series);
            }


            int traceInterval = (endTrace - startTrace + 1) / 5;


            //ChartPlot_Waveform.Dock = System.Windows.Forms.DockStyle.Fill;
            //设置属性
            ChartPlot_Waveform.ChartAreas[0].AxisX.Title = "Trace(s)";
            ChartPlot_Waveform.ChartAreas[0].AxisX.TitleFont = new System.Drawing.Font("Times new Roman", 8);
            ChartPlot_Waveform.ChartAreas[0].AxisX.Minimum = startTrace - 1;
            ChartPlot_Waveform.ChartAreas[0].AxisX.Maximum = endTrace + 1;
            ChartPlot_Waveform.ChartAreas[0].AxisX.Interval = traceInterval;
            ChartPlot_Waveform.ChartAreas[0].AxisX.MajorGrid.Enabled = false;

            ChartPlot_Waveform.ChartAreas[0].AxisY.IsReversed = true;
            ChartPlot_Waveform.ChartAreas[0].AxisY.Title = "Time / ms";
            ChartPlot_Waveform.ChartAreas[0].AxisY.Minimum = startTime;
            ChartPlot_Waveform.ChartAreas[0].AxisY.Maximum = endTime;
            //ChartPlot_Waveform.ChartAreas[0].AxisY.Interval = interval;
            ChartPlot_Waveform.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Gray;
            ChartPlot_Waveform.ChartAreas[0].AxisY.TitleFont = new System.Drawing.Font("Times new Roman", 8);

            ChartPlot_Waveform.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
            ChartPlot_Waveform.ChartAreas[0].BorderColor = System.Drawing.Color.Black;
            ChartPlot_Waveform.Legends.Clear();

            //

        }

调用函数是另外一个窗体的一个事件
调用函数如下:

private void WaveForm_Grapic_Button_Click(object sender, RoutedEventArgs e)
        {
            int k = 0;
            if (Data_IBM_ComboBox.IsSelected == true && Data_CheckBox.IsChecked == true)
                k = 1;
            else if (Data_IBM_ComboBox.IsSelected == true && Data_CheckBox.IsChecked == false)
                k = 2;
            else if (Data_IBM_ComboBox.IsSealed == false && Data_CheckBox.IsChecked == true)
                k = 3;
            else
                k = 4;

            Waveform waveform = new Waveform(fileStraeamOperater, nsamples, Convert.ToInt32(StartTrace.Text),
            Convert.ToInt32(EndTrace.Text), Convert.ToSingle(StartTime.Text), Convert.ToSingle(EndTime.Text), Convert.ToInt32(fileHead[5].Value) / 1000, k);
            waveform.Show();

        }

附一张200道的图吧,以便理解

img

另外:还有两个个问题:
1.我想正相位填充颜色:以第一道为例,其取值范围为0-1,以0.5为界,想将大于0.5的部分填充为纯色
2.绘制颜色图,类似于这样,两张图是同一个数据

img

请各位帮忙解决问题

  • 写回答

3条回答 默认 最新

  • 美羊羊桑7890 2023-04-12 22:31
    关注

    内容来源与ChatGpt4及newbing和百度:


    问题分析:

    1. 数据量达到1000道左右时,很卡,即使数据量不多,一两百道也要等好一会儿才出结果

    这个问题可能是由于绘制时使用了较为耗费资源的方式造成的。可以考虑使用DrawingVisual对象进行绘制,DrawingVisual对象比Canvas等容器对象更轻量级,绘制效率更高。

    1. 当该窗口被关闭时,没有释放资源

    可以在窗口关闭时,手动释放资源,如绘制所使用的DrawingVisual对象等。

    解决思路:

    1. 使用DrawingVisual对象进行绘制,可以通过以下代码创建DrawingVisual对象并添加到Canvas中:
    DrawingVisual visual = new DrawingVisual();
    using (DrawingContext dc = visual.RenderOpen())
    {
        //在DrawingContext中进行绘制
    }
    canvas.AddVisual(visual);
    
    1. 在窗口关闭时,手动释放资源,如下:
    protected override void OnClosed(EventArgs e)
    {
        //释放DrawingVisual对象等资源
        base.OnClosed(e);
    }
    

    代码示例:

    以下是使用DrawingVisual对象进行绘制的示例代码:

    private void DrawData(List<double> data)
    {
        if (data == null || data.Count == 0) return;
        //创建DrawingVisual对象并添加到Canvas中
        DrawingVisual visual = new DrawingVisual();
        using (DrawingContext dc = visual.RenderOpen())
        {
            double width = canvas.ActualWidth;
            double height = canvas.ActualHeight;
            double xInterval = width / data.Count;
            double yInterval = height / 2;
            Point start = new Point(0, yInterval);
            for (int i = 0; i < data.Count; i++)
            {
                double y = yInterval - data[i] * yInterval;
                Point end = new Point((i + 1) * xInterval, yInterval - data[i] * yInterval);
                dc.DrawLine(new Pen(Brushes.Black, 1), start, end);
                start = end;
            }
        }
        canvas.AddVisual(visual);
    }
    

    在窗口关闭时释放资源的代码示例:

    protected override void OnClosed(EventArgs e)
    {
        //释放DrawingVisual对象等资源
        canvas.ClearVisuals();
        base.OnClosed(e);
    }
    

    祝您问题迎刃而解

    评论

报告相同问题?

问题事件

  • 系统已结题 4月20日
  • 创建了问题 4月12日

悬赏问题

  • ¥20 python忆阻器数字识别
  • ¥15 无法输出helloworld
  • ¥15 高通uboot 打印ubi init err 22
  • ¥20 PDF元数据中的XMP媒体管理属性
  • ¥15 R语言中lasso回归报错
  • ¥15 网站突然不能访问了,上午还好好的
  • ¥15 有没有dl可以帮弄”我去图书馆”秒选道具和积分
  • ¥15 semrush,SEO,内嵌网站,api
  • ¥15 Stata:为什么reghdfe后的因变量没有被发现识别啊
  • ¥15 振荡电路,ADS仿真