Anzitutto, vedere http://www.robertovillari.it/makegradient.aspx in questo sito. Si tratta di una pagina che crea una immagine a gradiente dati alcuni parametri. L'idea mi è venuta perchè, essendo un programmatore con poca fantasia nella realizzazione di layout, ho notato che basta un fondo gradiente nei titoli dei box per avere un effetto piacevole.
Cercando in rete mi sono imbattuto in http://www.secretgeek.net/ColorWebService.asp ottimo ed utile servizio ma un po' troppo vincolante per un programmatore .NET. Il mio problema era creare tabelle ad una colonna e due righe (una per il titolo ed una come contenitore), ed applicare un background di sfondo a gradiente.
Per costruire un gradiente occorre specificare altezza e/o larghezza dell'immagine. Se si sviluppa il gradiente in verticale, è sufficiente specificare l'altezza ed una larghezza di 1px; se si sviluppa in orizzontale, al contrario, è sufficiente specificare la larghezza ed una altezza di 1px. Quindi, se sviluppiamo in orizzontale, è necessario che la larghezza della TD sia fissa... e questo puo' generare qualche problema se si vuole evitare problemi di "accessibilita'".
Opto quindi per lo sviluppo verticale, e definisco l'altezza della TD del titolo. Vado su secretgeek e produco l'immagine. Quindi, o uso il link generato da secretgeek, con tutti gli inconvenienti del caso (performance, sviluppo in locale), o salvo l'immagine sul mio PC.
Volendo, adesso secretgeek pubblica il sorgente in VB, ma non ho potuto resistere alla tentazione di scrivere il mio GradientImageHandler.ashx in C#. Si tratta di un handle http (e non una pagina aspx) richiamabile con una GET http, che specificando gli opportuni parametri, genera un jpeg. A questo punto, se si incorpora l'ashx nel proprio progetto, si possono usare ImageUrls che richiamano quell'handle, che a sua volta fornisce l'immagine desiderata.
Ovviamente, si può anche usare l'interfaccia http://www.robertovillari.it/MakeGradient.aspx e salvare il jpeg generato, ma i vantaggi nell'uso dell'handler ashx si vedono sia in fase di design (cambiando altezze o colori, non occorre fare il giro con il copia&incolla), sia in fase dinamica, ad esempio variando colore o altezza/larghezza in base alla risoluzione del browser o a scelte dell'utente.
Questo è il codice (alla vostra fantasia migliorarlo ed estenderne le funzioni) da inserire nel code-behind di una pagina con questa direttiva ASPX:
WebHandler Language="C#" Class="GradientImageHandler" System;
using System.IO;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D; class GradientImageHandler : IHttpHandler {
public bool IsReusable {get {return true;}}
public void ProcessRequest (HttpContext ctx)
{
// Inizializzo il response
ctx.Response.ContentType = "image/jpeg";
ctx.Response.Cache.SetCacheability(HttpCacheability.Public);
ctx.Response.BufferOutput = false;
GetParams(ctx);
// creo l'oggetto grafico e riempio il rettangolo con il gradiente
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height, PixelFormat.Format32bppArgb);
Graphics graphic = Graphics.FromImage(bitmap);
System.Drawing.Drawing2D.LinearGradientBrush gradiente = new System.Drawing.Drawing2D.LinearGradientBrush(new RectangleF(0, 0, width, height), startColor, endColor, gradientMode);
graphic.FillRectangle(gradiente, new RectangleF(0, 0, width, height));// disegno l'eventuale testo
if (text != "") graphic.DrawString(text, textFont, new SolidBrush(textColor), new PointF(0, 0));// Salvo nello stream l'immagine e poi la invio in output
}MemoryStream MemStream = new MemoryStream();
bitmap.Save(MemStream, ImageFormat.Jpeg);
MemStream.WriteTo(ctx.Response.OutputStream);
bitmap.Dispose(); private int width = 200;
private int height = 50;
private Color startColor = Color.FromArgb(127, 127, 127);
private Color endColor = Color.FromArgb(255, 255, 255);
private System.Drawing.Drawing2D.LinearGradientMode gradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical;private string text = "";
private Font textFont = new Font("Verdana", 12, FontStyle.Regular);
private Color textColor = Color.FromArgb(255, 255, 255);
private bool useNamedColor = false;private void GetParams(HttpContext context)
{if (context.Request.QueryString["Width"] != null && context.Request.QueryString["Width"].ToString() != "") Int32.TryParse(context.Request.QueryString["Width"].ToString(), out width);if (context.Request.QueryString["Height"] != null && context.Request.QueryString["Height"].ToString() != "") Int32.TryParse(context.Request.QueryString["Height"].ToString(), out height);if (context.Request.QueryString["Text"] != null) text = context.Request.QueryString["Text"].ToString();if (context.Request.QueryString["StartColor"] != null && context.Request.QueryString["StartColor"].ToString() != "") startColor = GetColorParam(context.Request.QueryString["StartColor"].ToString());if (context.Request.QueryString["EndColor"] != null && context.Request.QueryString["EndColor"].ToString() != "") endColor = GetColorParam(context.Request.QueryString["EndColor"].ToString());if (context.Request.QueryString["UseNamedColor"] != null && context.Request.QueryString["UseNamedColor"].ToString() != "")
useNamedColor = ((bool)(context.Request.QueryString["UseNamedColor"].ToString() != "0"));if (context.Request.QueryString["Mode"] != null)
switch (context.Request.QueryString["Mode"].ToString())
{
case "H": gradientMode = System.Drawing.Drawing2D.LinearGradientMode.Horizontal; break;
case "V": gradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical; break;
case "B": gradientMode = System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal; break;
case "F": gradientMode = System.Drawing.Drawing2D.LinearGradientMode.ForwardDiagonal; break;
default: gradientMode = System.Drawing.Drawing2D.LinearGradientMode.Vertical; break;
}
if (context.Request.QueryString["Text"] != null)
{
text = context.Request.QueryString["Text"].ToString();
if (context.Request.QueryString["TextColor"] != null && context.Request.QueryString["TextColor"].ToString() != "")
textColor = GetColorParam(context.Request.QueryString["TextColor"].ToString());
}
if (context.Request.QueryString["FontSize"] != null)
{
int fontsize;
if (Int32.TryParse(context.Request.QueryString["FontSize"].ToString(), out fontsize))
textFont = new Font("Verdana", fontsize, FontStyle.Regular);
}
}
private Color GetColorParam(string c)
{
int alfa = 255;
try
{
if (!String.IsNullOrEmpty(c))
{
if (c.StartsWith("#")) { useNamedColor = false; c = c.Remove(0, 1); }
if (!useNamedColor) // #rrggbb
{
if (c.Length > 6) c = c.Substring(0, 6);
c = c.PadLeft(6, '0');
long kR = Convert.ToInt64(c.Substring(0, 2), 16);
long kG = Convert.ToInt64(c.Substring(2, 2), 16);
long kB = Convert.ToInt64(c.Substring(4, 2), 16);
return Color.FromArgb(alfa, (int)kR, (int)kG, (int)kB);
}
else return Color.FromName(c);
}
}
catch { }
return new Color();
}
}
using public