none
Problemas ao tentar migrar um gráfico chart para uma PictureBox RRS feed

  • Pergunta

  • Olá, pessoal!

    Estou tentando plotar um gráfico de representativo de um ECG (eletrocardiograma) em uma PictureBox (Windows Form, C#). Os dados da curva do ecg estão em um array e eu consigo plotar eles sem problemas em um chart conforme código a seguir:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace PlotagemGrafica
    {
        public partial class Form1 : Form
        {
            int x = 10;
    
            Byte[] curva_ecg =
                {
                0x5a,0x5a,0x5a,0x5b,0x5b,0x5c,0x5c,0x5d,	//0
                0x5d,0x5e,0x5e,0x5f,0x60,0x60,0x61,0x61,
                0x62,0x62,0x63,0x63,0x64,0x64,0x65,0x65,
                0x66,0x67,0x67,0x68,0x68,0x69,0x69,0x6a,
                0x6a,0x6b,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,
                0x6c,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6e,	//40
                0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6d,0x6d,
                0x6d,0x6d,0x6c,0x6c,0x6c,0x6b,0x6b,0x6a,
                0x6a,0x6a,0x69,0x69,0x68,0x68,0x67,0x67,
                0x66,0x66,0x65,0x65,0x64,0x64,0x63,0x63,
                0x62,0x61,0x61,0x60,0x5f,0x5f,0x5e,0x5e,	//80
                0x5d,0x5d,0x5c,0x5c,0x5b,0x5b,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,	//120
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x59,0x57,0x54,0x52,0x4f,0x4d,0x4a,
                0x48,0x45,0x43,0x40,0x3e,0x3d,0x3d,0x3e,
                0x3f,0x44,0x4a,0x4f,0x55,0x5b,0x60,0x66,	//160
                0x6b,0x71,0x76,0x7c,0x82,0x87,0x8d,0x92,
                0x98,0x9d,0xa3,0xa8,0xae,0xb4,0xb9,0xbf,
                0xc4,0xca,0xcf,0xd5,0xdb,0xe0,0xe6,0xe1,
                0xdb,0xd6,0xd1,0xcc,0xc6,0xc1,0xbc,0xb7,
                0xb1,0xac,0xa7,0xa2,0x9c,0x97,0x92,0x8c,	//200
                0x87,0x82,0x7d,0x77,0x72,0x6d,0x68,0x62,
                0x5d,0x58,0x53,0x4d,0x48,0x43,0x3e,0x38,
                0x33,0x30,0x2d,0x2d,0x2e,0x31,0x34,0x37,
                0x3b,0x3e,0x41,0x44,0x47,0x4a,0x4e,0x51,
                0x54,0x56,0x58,0x58,0x59,0x59,0x59,0x59,	//240
                0x59,0x59,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,	//280
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5b,0x5b,0x5b,
                0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,0x5e,
                0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,0x61,
                0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x63,	//320
                0x64,0x64,0x64,0x64,0x65,0x65,0x65,0x66,
                0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x69,
                0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,
                0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,
                0x6e,0x6f,0x6f,0x6f,0x6f,0x70,0x70,0x70,	//360
                0x70,0x71,0x71,0x71,0x72,0x72,0x72,0x72,
                0x73,0x73,0x73,0x73,0x74,0x74,0x74,0x74,
                0x75,0x75,0x75,0x75,0x76,0x76,0x76,0x76,
                0x77,0x77,0x77,0x77,0x77,0x77,0x78,0x78,
                0x78,0x78,0x78,0x78,0x78,0x78,0x78,0x78,	//400
                0x79,0x79,0x79,0x79,0x79,0x79,0x79,0x79,
                0x79,0x78,0x78,0x78,0x78,0x78,0x78,0x78,
                0x78,0x77,0x77,0x77,0x77,0x77,0x76,0x76,
                0x75,0x75,0x74,0x74,0x74,0x73,0x73,0x72,
                0x72,0x71,0x71,0x70,0x70,0x6f,0x6f,0x6e,	//440
                0x6d,0x6d,0x6c,0x6b,0x6b,0x6a,0x6a,0x69,
                0x68,0x68,0x67,0x66,0x66,0x65,0x64,0x64,
                0x63,0x62,0x62,0x61,0x60,0x60,0x5f,0x5e,
                0x5e,0x5d,0x5c,0x5b,0x5b,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,	//480
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,	//520
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,	//560
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                };
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                chtGrafico.Legends.Clear();
                chtGrafico.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Spline;
    
            }
    
            int i = 0;
            private void timer_Tick(object sender, EventArgs e)
            {
                if (i > curva_ecg.Length - 1)
                    i = 0;
                if (chtGrafico.Series[0].Points.Count > 1000)
                {
                    chtGrafico.Series[0].Points.Clear();
                 
                    chtGrafico.Update();
                }
                i++;
                chtGrafico.Series[0].Points.AddXY(x++, curva_ecg[i]);
            }
        }
    }

    Porém, ao tentar plotar esta mesma curva do ECG em uma PictureBox, a imagem plotada parece um gráfico de onda quadrada:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace DrawGraphics
    {
        public partial class Form1 : Form
        {
            Byte[] curva_ecg =
                {
                0x5a,0x5a,0x5a,0x5b,0x5b,0x5c,0x5c,0x5d,	//0
                0x5d,0x5e,0x5e,0x5f,0x60,0x60,0x61,0x61,
                0x62,0x62,0x63,0x63,0x64,0x64,0x65,0x65,
                0x66,0x67,0x67,0x68,0x68,0x69,0x69,0x6a,
                0x6a,0x6b,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,
                0x6c,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6e,	//40
                0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6d,0x6d,
                0x6d,0x6d,0x6c,0x6c,0x6c,0x6b,0x6b,0x6a,
                0x6a,0x6a,0x69,0x69,0x68,0x68,0x67,0x67,
                0x66,0x66,0x65,0x65,0x64,0x64,0x63,0x63,
                0x62,0x61,0x61,0x60,0x5f,0x5f,0x5e,0x5e,	//80
                0x5d,0x5d,0x5c,0x5c,0x5b,0x5b,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,	//120
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x59,0x57,0x54,0x52,0x4f,0x4d,0x4a,
                0x48,0x45,0x43,0x40,0x3e,0x3d,0x3d,0x3e,
                0x3f,0x44,0x4a,0x4f,0x55,0x5b,0x60,0x66,	//160
                0x6b,0x71,0x76,0x7c,0x82,0x87,0x8d,0x92,
                0x98,0x9d,0xa3,0xa8,0xae,0xb4,0xb9,0xbf,
                0xc4,0xca,0xcf,0xd5,0xdb,0xe0,0xe6,0xe1,
                0xdb,0xd6,0xd1,0xcc,0xc6,0xc1,0xbc,0xb7,
                0xb1,0xac,0xa7,0xa2,0x9c,0x97,0x92,0x8c,	//200
                0x87,0x82,0x7d,0x77,0x72,0x6d,0x68,0x62,
                0x5d,0x58,0x53,0x4d,0x48,0x43,0x3e,0x38,
                0x33,0x30,0x2d,0x2d,0x2e,0x31,0x34,0x37,
                0x3b,0x3e,0x41,0x44,0x47,0x4a,0x4e,0x51,
                0x54,0x56,0x58,0x58,0x59,0x59,0x59,0x59,	//240
                0x59,0x59,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,	//280
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5b,0x5b,0x5b,
                0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,0x5e,
                0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,0x61,
                0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x63,	//320
                0x64,0x64,0x64,0x64,0x65,0x65,0x65,0x66,
                0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x69,
                0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,
                0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,
                0x6e,0x6f,0x6f,0x6f,0x6f,0x70,0x70,0x70,	//360
                0x70,0x71,0x71,0x71,0x72,0x72,0x72,0x72,
                0x73,0x73,0x73,0x73,0x74,0x74,0x74,0x74,
                0x75,0x75,0x75,0x75,0x76,0x76,0x76,0x76,
                0x77,0x77,0x77,0x77,0x77,0x77,0x78,0x78,
                0x78,0x78,0x78,0x78,0x78,0x78,0x78,0x78,	//400
                0x79,0x79,0x79,0x79,0x79,0x79,0x79,0x79,
                0x79,0x78,0x78,0x78,0x78,0x78,0x78,0x78,
                0x78,0x77,0x77,0x77,0x77,0x77,0x76,0x76,
                0x75,0x75,0x74,0x74,0x74,0x73,0x73,0x72,
                0x72,0x71,0x71,0x70,0x70,0x6f,0x6f,0x6e,	//440
                0x6d,0x6d,0x6c,0x6b,0x6b,0x6a,0x6a,0x69,
                0x68,0x68,0x67,0x66,0x66,0x65,0x64,0x64,
                0x63,0x62,0x62,0x61,0x60,0x60,0x5f,0x5e,
                0x5e,0x5d,0x5c,0x5b,0x5b,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,	//480
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,	//520
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,	//560
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,
                };
    
            const int historyLength = 512;
            float[] history = new float[historyLength];
            int nextWrite = 0;
            Graphics bmg;
            Bitmap bm;
    
            private System.Windows.Forms.PictureBox pictureBox1;
            private System.Windows.Forms.Timer timer1;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                // set initial values
                for (int i = 0; i < historyLength; i++)
                {
                    history[i] = 0;
                }
            }
    
            private void pictureBox1_Paint(object sender, PaintEventArgs e)
            {
                if (bm == null)
                {
                    bm = new Bitmap(historyLength, 101);
                    bmg = Graphics.FromImage(bm);
                    bmg.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; //COMENTAR
                    bmg.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.GammaCorrected; //COMENTAR
                    bmg.Clear(Color.White);
                }
                Render();
                e.Graphics.DrawImage(bm, 0, 0);
            }
    
            void Render()
            {
                bmg.Clear(Color.White);
                float y0 = 0;
                int x0 = 0;
                for (int i = 0; i < historyLength; i++)
                {
                    float y = 50.0f + 50.0f * history[(nextWrite + i) % historyLength];
                    int x = i;
                    if (i != 0)
                    {
                        // draw a line
                        bmg.DrawLine(Pens.Black, x0, y0, x, y);
                    }
                    y0 = y;
                    x0 = x;
                }
            }
    
            int t = 0;
            private void timer1_Tick(object sender, EventArgs e)
            {
                AddValue(curva_ecg[t] / 120);
                t++;
                this.pictureBox1.Invalidate();
            }
    
            void AddValue(int y)
            {
                history[nextWrite] = y;
                nextWrite = (nextWrite + 1) % historyLength;
            }
        }
    }

    O curioso é que este código eu usei como base para plotar uma senóide a qual saiu perfeita:

    Existe algum tratamento que deve ser feito em um array para que ele seja plotado em uma PictureBox com base no tempo do timer?



    • Editado LD_7 domingo, 3 de janeiro de 2021 00:34
    domingo, 3 de janeiro de 2021 00:31

Todas as Respostas

  • LD_7,

       Posso estar enganado, mas acho que NÃO dá para fazer isso direto.
       Talvez você precise salvar em uma imagem (e não precise gravar no disco colocando a array em uma variável) e depois ler esta imagem dentro de uma PictureBox.
       Mas, por favor, veja os link abaixo.


    ================================================
    C# - Convertendo Imagem para Array de bytes e vice-versa

    http://www.macoratti.net/19/11/c_imgarr1.htm
    ================================================
    Chart.SaveImage Método

    https://docs.microsoft.com/pt-br/dotnet/api/system.windows.forms.datavisualization.charting.chart.saveimage?view=netframework-4.8
    ================================================
    Bitmap Classe

    https://docs.microsoft.com/pt-br/dotnet/api/system.drawing.bitmap?view=dotnet-plat-ext-5.0
    ================================================


    []'s,
    Fabio I.
    • Editado Fabio I segunda-feira, 4 de janeiro de 2021 01:20
    segunda-feira, 4 de janeiro de 2021 01:20
  • Ola

    Obrigada por contatar Microsoft.

    Acredito que nao sera possivel fazer o que voce deseja usando PictureBox - e por um simples motivo:

    "Normalmente, o PictureBox é usado para exibir gráficos de um bitmap, metarquivo, ícone, JPEG, gif ou arquivo PNG."

    PictureBox Classe (System.Windows.Forms) | Microsoft Docs

    Espero que tenha ajudado.

    segunda-feira, 4 de janeiro de 2021 19:43
    Moderador
  • Olá, JuColombo!

    Obrigado pelo comentário :)

    Sobre a questão da PictureBox, me desculpe se a minha pergunta for muito "noob", mas por que eu consigo plottar uma senóide dinâmica (sendo plotada em tempo real de acordo com a frequência do timer) nele e mesmo assim não é possível plottar a função de um array nele?

    terça-feira, 5 de janeiro de 2021 11:57
  • Oi, Fábio!

    Agradeço pela resposta =)

    Sobre a questão da PictureBox, me desculpe se a minha pergunta for muito "noob", mas por que eu consigo plottar uma senóide dinâmica (sendo plotada em tempo real de acordo com a frequência do timer) nele e mesmo assim não é possível plottar a função de um array nele?

    terça-feira, 5 de janeiro de 2021 11:57
  • LD_7,

        Não tenho certeza, mas acredito que sim, experimente ler e fazer o link que passei do José Carlos Macoratti e veja se atende o que você está tentando fazer.

    []'s,
    Fabio I.

    terça-feira, 5 de janeiro de 2021 12:31
  • Ok, muito obrigado :)
    quinta-feira, 7 de janeiro de 2021 13:56