es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo dibujar un ECG simulado

Lo que me gustaría crear (no tiene que ser muy preciso, es solo para fines de entretenimiento):

DEMO de ECG

imagen de descripción

Imagen de ECG

Imagen de ECG

Lo que tengo:

Tengo una API REST a un servicio que me permite consultar el BPM actual de la persona que lleva el dispositivo de medición de pulso. Así que no tengo un evento que indique cuándo se produce un latido cardíaco. Tendría que calcular esto con el BPM proporcionado. Pero eso no es el problema.

La pregunta:

¿Cómo dibujarías las líneas y hacer que desaparezcan detrás y de izquierda a derecha con un reinicio cuando llegue a la esquina derecha? Tengo algo de experiencia en C# WPF, por eso creé las consultas REST allí. ¿Existen algunas bibliotecas para la parte de dibujo? ¿Hay alguna forma fácil de hacer esto manualmente?

Realmente agradezco cualquier consejo, ya que no puedo encontrar mucha información sobre un problema bastante específico como este en Internet. ¡Así que gracias!

ACTUALIZACIÓN:
Logré hacer algo funcionar usando WritableBitmap, pero se ve bastante mal. ¿Alguna idea de cómo obtener una mejor resolución? Ya aumenté la resolución del mapa de bits, pero aún se ve bastante horrible. ¿Hay algún tipo de suavizado en esto?

DEMO

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para lograr el efecto deseado de dibujar líneas y hacer que desaparezcan de izquierda a derecha con un reinicio cuando llegan a la esquina derecha, puedes usar la biblioteca WPF en C# y la clase WritableBitmap.

    En primer lugar, necesitas crear un lienzo donde se dibujarán tus líneas. Puedes hacer esto creando una ventana WPF y agregando un elemento de lienzo.

    <window x:class="ECGDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" title="ECG Demo" height="500" width="800">
             <canvas x:name="Canvas"></canvas>
    </window>
    

    Una vez que tengas tu lienzo, puedes crear un objeto WritableBitmap que almacenará los píxeles de tus líneas. Establece las dimensiones del mapa de bits para que coincidan con el tamaño de tu lienzo.

    var bitmap = new WriteableBitmap((int)Canvas.ActualWidth, (int)Canvas.ActualHeight, 96, 96, PixelFormats.Bgr32, null);
    

    A continuación, puedes dibujar tus líneas en el mapa de bits en forma de datos de píxeles utilizando el método “WritePixels” de WriteableBitmap. Puedes usar el “DrawingContext” proporcionado para dibujar líneas que coincidan con las BPM de la persona que lleva el dispositivo de medición de pulso.

    using (var context = bitmap.WriteableBitmapContext())
    {
        context.DrawLine(...); // dibuja tu línea aquí
    }
    

    Para lograr el efecto de desaparición, puedes desplazar los píxeles hacia la izquierda cada vez que dibujes una nueva línea, lo que efectivamente hace que las líneas se muevan de derecha a izquierda. Cuando las líneas alcanzan el límite izquierdo del lienzo, restablece los datos de píxeles para dibujar las líneas desde la derecha nuevamente.

    bitmap.Lock();
    var pixelData = new byte[(int)Canvas.ActualWidth * (int)Canvas.ActualHeight * 4]; // 4 bytes para cada píxel
    bitmap.CopyPixels(pixelData, (int)Canvas.ActualWidth * 4, 0);
    
    // desplaza los píxeles hacia la izquierda
    var stride = (int)Canvas.ActualWidth * 4;
    for (var y = 0; y < Canvas.ActualHeight; y++)
    {
        for (var x = 4; x < stride; x += 4)
        {
            pixelData[y * stride + x - 4] = pixelData[y * stride + x];
            pixelData[y * stride + x - 3] = pixelData[y * stride + x + 1];
            pixelData[y * stride + x - 2] = pixelData[y * stride + x + 2];
            pixelData[y * stride + x - 1] = pixelData[y * stride + x + 3];
        }
        pixelData[y * stride + stride - 4] = 0;
        pixelData[y * stride + stride - 3] = 0;
        pixelData[y * stride + stride - 2] = 0;
        pixelData[y * stride + stride - 1] = 0;
    }
    
    // restablece los datos de píxeles cuando alcanza el límite izquierdo
    if (currentX < 0 || currentX > (int)Canvas.ActualWidth)
    {
        pixelData = new byte[(int)Canvas.ActualWidth * (int)Canvas.ActualHeight * 4];
        currentX = (int)Canvas.ActualWidth;
    }
    
    bitmap.WritePixels(new Int32Rect(0, 0, (int)Canvas.ActualWidth, (int)Canvas.ActualHeight), pixelData, stride, 0);
    bitmap.Unlock();
    

    Para aumentar la resolución de tu objeto WritableBitmap, puedes intentar aumentar los DPI al crear el objeto. También puedes experimentar con diferentes formatos de píxeles para mejorar la calidad de la imagen.

    También hay bibliotecas disponibles para dibujar en C# WPF, como SkiaSharp y DrawingVisual. Estas pueden proporcionar características de dibujo más avanzadas, pero pueden ser más difíciles de usar que la clase WritableBitmap.

Comments are closed.