C# rectángulos más rápidos que DrawRectangle

Tamaño de letra:

C# y la lentitud

Desde mi punto de vista, C# (C Sharp) es uno de los lenguajes de programación más populares. El uso de la biblioteca Microsoft .NET hace sencillas las cosas difíciles pero muchas veces he desistido de usarlo (en vez de VC++) debido en algunos casos a la lentitud. Hoy os voy a poner un ejemplo con DrawRectangle y cómo lo he solucionado...

El problema de lentitud de DrawRectangle

Aunque C# es espectacular y en segundos puedes crear aplicaciones que con C++ tartarías horas, en algunos casos puede llegar a desesperar su lentitud y resulta que pierdes más tiempo en optimizar el código que en programarlo en otro lenguaje. Eso me ha pasado con mi último programa y pienso que la lentitud de un programa puede hacer perder el interés del usuario que quiera comprártelo.

Desde hace años se sabe que la función DrawRectangle es lenta (busca en la red para comprobarlo). Te lo voy a demostrar:

Simplemente crea el método: private void frm_miformulario_MouseMove(object sender, MouseEventArgs e), y cuando se ejecute el evento MouseMove (movimiento del ratón) empieza a crear rectángulos con grafico.DrawRectangle(Milapiz, punto.X, punto.Y, AnchoRectangulo, AltoRectangulo); //(grafico lo tengo definido en el formulario padre)

Cuando los rectángulos son de pequeñas dimensiones no pasa nada pero cuando los rectángulos ocupan toda la pantalla el dibujo de los mismos se ralentiza enormemente. Además está el inconveniente de que tienes que dibujar otro para borrar el anterior y además produce parpadeos aunque utilices un buffer secundario (this.DoubleBuffered = true;).

A este problema le he dado muchas vueltas y al final he encontrado una solución que hace los rectángulos muchísimo más rápidos.

He creado la siguiente subrutina:

private void rectangulo(Color color, Point VerticeTopLeft, Point VerticeBottomRight)
        {
            int AnchoRectangulo = VerticeBottomRight.X - VerticeTopLeft.X;
            int AltoRectangulo = VerticeBottomRight.Y - VerticeTopLeft.Y;
            Bitmap bm = new Bitmap(AnchoRectangulo, AltoRectangulo);
 
            for (int x = 0; x < AnchoRectangulo; x++)
            {
                bm.SetPixel(x, 0, color);
                bm.SetPixel(x, AltoRectangulo-1, color);
            }
            for (int y = 0; y < AltoRectangulo; y++)
            {
                bm.SetPixel(0, y, color);
                bm.SetPixel(AnchoRectangulo-1, y, color);
            }
            grafico.DrawImageUnscaled(bm, VerticeTopLeft);
            bm.Dispose();
        }
 

Verás que he definido anteriormente "grafico" y que para hacer el rectángulo creo un bitmap que pinto posteriormente.

Conclusiones

Este código es muchísimo más rápido que DrawRectangle pero aún así queda algo lento si lo comparas con otros programas realizados con otros lenguajes de programación (por ejemplo Delphi que es instantáneo).

Sólo espero que a alguno le pueda servir. Voy a seguir programando con C#.

Última actualización: Lunes, 09 Enero 2012
Comentarios  
0 # rahegon 04-03-2016 11:07
Buenas, la verdad que tiene muy buena pinta el post, pero tipo de objeto es grafico? como lo defines? esque soy nuevo en esto... espero no hacer el ridiculo preguntando XD
0 # karmany 04-03-2016 19:55
Tienes razón, no está especificado.
Para definir el gráfico puedes hacerlo así dentro de tu clase:
Código:System.Drawing.Graphics grafico

En mi caso yo lo usé en un formulario, y lo inicialicé así:
Código:public myForm()
{
InitializeComponent();
...
grafico = this.CreateGraphics();
}


Espero que te sirva...

No tiene privilegios para responder a los comentarios.


 
Visitas: 8567600