Con questo articolo cerco di mostrare come utilizzare le API GDI+ del .Net Framework per combinare tra loro immagini esistenti e virtuali, il tutto a runtime.
Si leggono di molte richieste d'aiuto nei vari forums su come sovrapporre più immagini utilizzando gli strumenti forniti da .Net, penso che l'esempio che sto per
trattare sia parecchio utile ed esplicativo.
Al solito definiamo uno scenario verosimile per contestualizzare la teoria astratta:
- finalità
creare un'immagine per la visualizzazione, tramite le "classiche" stelle, di un rating variabile da 0 a 5 (valori di tipo double, vale a dire non arrotondati agli interi prossimi)
- mezzi
C#, GDI+ e Adobe® Photoshop, o analogo (per la creazione delle immagini base)
L'idea è quella di assemblare un'immagine a mo' di sandwich, strutturata su vari livelli disposti lungo l'asse z (del monitor).
- Sul livello più basso predisponiamo un immagine di sfondo che agirà anche da segnaposto per le stellette "spente". L'immagine che vado a riportare
è esattamente quella utilizzata in questo blog:

- sul livello intermedio andiamo a disegnare un rettangolo giallo-oro di larghezza variabile, in funzione del valore numerico del rating;
- sul livello prossimo agli occhi dell'utente disponiamo un'immagine, forata ed arricchita di effetti di smusso, di base bianca (colore dello sfondo della pagina):

Vediamo ora il codice C# utilizzato:
float rating = Convert.ToSingle(Request.QueryString["Rating"], System.Globalization.CultureInfo.InvariantCulture)/5F;
Pacem.Drawing.Image pacemimg = new Pacem.Drawing.Image(Server.MapPath("~/Images/CMerighi/Rating_Lower.png"));
Bitmap rect = new Bitmap(pacemimg.Width, pacemimg.Height);
Graphics graph = Graphics.FromImage(rect);
graph.FillRectangle(Brushes.Gold, new RectangleF(0F, 0F, ((float)pacemimg.Width)*rating, (float)pacemimg.Height));
pacemimg.OverlayImage(rect, Pacem.Drawing.VerticalAnchor.Top, Pacem.Drawing.HorizontalAnchor.Left);
pacemimg.OverlayImage(Server.MapPath("~/Images/CMerighi/Rating_Upper.png"), Pacem.Drawing.VerticalAnchor.Top, Pacem.Drawing.HorizontalAnchor.Left);
rect.Dispose(); graph.Dispose();
Response.ContentType = "image/png";
pacemimg.Flush(Response.OutputStream, "image/png");
pacemimg.Dispose();
La classe Pacem.Drawing.Image è una classe da me sviluppata per la manipolazione delle immagini.
Contiene metodi per lo scaling, il ridimensionamento dell'area visualizzabile e soprattutto
della manipolazione del colore stile Photoshop con algoritmi che danno risultati pressoché identici
a quelli del software della Adobe®. Se ci sono tool che rendono meglio la colorazione fatemeli conoscere.
Vediamo di analizzare una forma del metodo OverlayImage (overloaded), mostrando come agisce. Eccone il codice per esteso:
public void OverlayImage(
System.Drawing.Image bmp,
VerticalAnchor vAnchor,
HorizontalAnchor hAnchor
)
{
Graphics graph = Graphics.FromImage(bmp);
int x, y;
double W, w, H, h;
W = (double)_Bitmap.Width; H = (double)_Bitmap.Height;
w = (double)bmp.Width; h = (double)bmp.Height;
switch (vAnchor)
{
case VerticalAnchor.Middle:
y = (int)((H - h) / 2);
break;
case VerticalAnchor.Bottom:
y = _Bitmap.Height - bmp.Height;
break;
default:
y = 0;
}
switch (hAnchor)
{
case HorizontalAnchor.Center:
x = (int)((W - w) / 2);
break;
case HorizontalAnchor.Right:
x = _Bitmap.Width - bmp.Width;
break;
default:
x = 0;
}
Rectangle destR = new Rectangle(x, y, bmp.Width, bmp.Height);
Bitmap _Bmp = new Bitmap(_Bitmap.Width, _Bitmap.Height);
Graphics _Graph = Graphics.FromImage(_Bmp);
_Graph.DrawImage(_Bitmap, 0, 0, _Bitmap.Width, _Bitmap.Height);
_Graph.DrawImage(bmp, destR, new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
_Bitmap = _Bmp;
_Graphics = Graphics.FromImage(_Bitmap);
bmp.Dispose(); graph.Dispose(); _Graph.Dispose();
}
Penso sia tutto.
Take care. Bye.
Feedbacks
no feedbacks yet.