Este fin de semana he estado trabajando en una pequeña aplicación que en breve colgaré con código fuente para todo el mundo y que me dio el error que os comento en el título del post.

Aunque todo lo que utilicé era compatible con .NET 2.0, la desarrollé en mi equipo con Visual Studio 2010 y .NET 4.0, donde todo funcionaba a la perfección. Al subirla al servidor donde iba a estar albergada, de repente, me daba el error "Error genérico de GDI+" o -en inglés- "A generic error occurred in GDI+", sin más explicaciones, y con unas referencias muy raras a Remoting.

Mi código original generaba una imagen que posteriormente se devolvía al navegador en formato PNG. El código que estaba utilizando era similar al siguiente:

Bitmap img = new Bitmap(sRutaImagenPatron);
Graphics g = Graphics.FromImage(img);
Font f = new Font(fuente, tamanio, FontStyle.Bold);
Brush b = colorLetra;
g.DrawString(string.Format("{0:n0}", iDato), f, b, posX_Letra, posY_Letra);

context.Response.ContentType = "image/png";
img.Save(context.Response.OutputStream, ImageFormat.Png);

Las primeras líneas, antes de la que está en negrita al final, se encargan de generar el gráfico sobreponiendo un texto a partir de un gráfico inicial que tengo en disco. La línea importante es la última, que se encarga de guardar el gráfico resultante al flujo de salida de la petición actual, de modo que lo reciba el usuario en su navegador.

El motivo de que se produzca este error es que en las versiones anteriores de .NET el Stream de respuesta de ASP.NET no permite moverse adelante y atrás por él, es decir, lo que escribes ese añade al final y nada más. El caso es que el formato PNG para poder escribirse correctamente necesita moverse a lo largo del stream, y por eso rompe el código anterior al intentar escribir directamente en la salida de la respuesta actual (Response).

La solución que funciona siempre: generar el gráfico en un stream en memoria que siempre permiten el movimiento en todas direcciones, y luego enviar el resultado de una vez al Response. En código C# esto es así:

using (MemoryStream stream = new MemoryStream())
{
    img.Save(stream, ImageFormat.Png);
    stream.WriteTo(context.Response.OutputStream);
}

Si sustituimos la última línea anterior con este fragmento obtendremos el mismo resultado (la imagen enviada al cliente) pero sin que se produzca el error anterior, ya que el stream en memoria se puede mover adelante y atrás sin problema.

¡Espero que te resulte útil!

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor

Escrito por un humano, no por una IA